kaleido-mcp 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.
package/dist/server.js ADDED
@@ -0,0 +1,106 @@
1
+ /**
2
+ * kaleido-mcp — Unified WDK MCP Server
3
+ *
4
+ * Assembles a single WdkMcpServer (from @tetherto/wdk-mcp-toolkit) that contains:
5
+ *
6
+ * LAYER 1 — WDK built-in tools (via registerTools):
7
+ * • WALLET_TOOLS — getAddress, getBalance, sendTransaction, transfer,
8
+ * getTokenBalance, quoteSendTransaction, quoteTransfer,
9
+ * getFeeRates, sign, verify (all scoped to 'spark' chain)
10
+ * • PRICING_TOOLS — getCurrentPrice, getHistoricalPrice (Bitfinex)
11
+ *
12
+ * LAYER 2 — Custom Spark tools (Lightning invoices, BTC bridge, fee-free transfers):
13
+ * spark_get_balance, spark_get_address, spark_create_lightning_invoice, spark_pay_lightning_invoice,
14
+ * spark_quote_lightning_payment, spark_get_deposit_address,
15
+ * spark_quote_withdraw, spark_withdraw, spark_get_transfers,
16
+ * spark_send_sats, spark_transfer_token, spark_mpp_pay, spark_get_token_balance
17
+ *
18
+ * LAYER 3 — RLN (RGB Lightning Node) tools:
19
+ * wdk_get_node_info, wdk_get_balances, wdk_list_assets, wdk_get_asset_balance,
20
+ * wdk_get_address, wdk_create_rgb_invoice, wdk_create_ln_invoice,
21
+ * wdk_pay_invoice, wdk_send_btc, wdk_send_asset, wdk_list_channels,
22
+ * wdk_connect_peer, wdk_open_channel, wdk_list_payments,
23
+ * wdk_refresh_transfers, wdk_atomic_taker, wdk_list_swaps,
24
+ * wdk_get_swap, wdk_mpp_pay
25
+ *
26
+ * LAYER 4 — KaleidoSwap DEX tools:
27
+ * kaleidoswap_get_assets, kaleidoswap_get_pairs, kaleidoswap_get_quote,
28
+ * kaleidoswap_get_spreads, kaleidoswap_place_order, kaleidoswap_get_order_status,
29
+ * kaleidoswap_get_open_orders, kaleidoswap_cancel_order, kaleidoswap_get_position,
30
+ * kaleidoswap_atomic_init, kaleidoswap_atomic_execute, kaleidoswap_atomic_status,
31
+ * kaleidoswap_lsp_get_info, kaleidoswap_lsp_estimate_fees,
32
+ * kaleidoswap_lsp_create_order, kaleidoswap_lsp_get_order
33
+ *
34
+ * LAYER 5 — MPP / L402 / 402index.io:
35
+ * mpp_request_challenge, mpp_submit_credential, mpp_parse_challenge_header,
36
+ * l402_request_challenge, l402_fetch_resource, search_paid_apis
37
+ *
38
+ * LAYER 6 — Market data (CoinGecko / alternative.me):
39
+ * l402_get_price, l402_get_market_data, l402_get_ohlcv, l402_get_sentiment
40
+ *
41
+ * Legacy aliases are retained temporarily for older `rln_*` and generic `get_*` callers.
42
+ */
43
+ import { WdkMcpServer, WALLET_TOOLS, PRICING_TOOLS } from '@tetherto/wdk-mcp-toolkit';
44
+ // @ts-ignore — ESM/CJS compat
45
+ import WalletManagerSpark from '@tetherto/wdk-wallet-spark';
46
+ import { KaleidoClient } from 'kaleido-sdk';
47
+ import { registerRlnTools } from './tools/rln-tools.js';
48
+ import { registerSparkTools } from './tools/spark-tools.js';
49
+ import { registerKaleidoswapTools } from './tools/kaleidoswap-tools.js';
50
+ import { registerMppTools } from './tools/mpp-tools.js';
51
+ import { registerMarketTools } from './tools/market-tools.js';
52
+ export function createServer(config) {
53
+ // -------------------------------------------------------------------------
54
+ // 1. Bootstrap WdkMcpServer — Spark tools only if WDK_SEED is provided
55
+ // -------------------------------------------------------------------------
56
+ const server = new WdkMcpServer('kaleido-mcp', '1.0.0');
57
+ if (config.wdkSeed) {
58
+ try {
59
+ server
60
+ .useWdk({ seed: config.wdkSeed })
61
+ .registerWallet('spark', WalletManagerSpark, {
62
+ network: config.sparkNetwork,
63
+ ...(config.sparkScanApiKey ? { sparkScanApiKey: config.sparkScanApiKey } : {}),
64
+ })
65
+ .usePricing()
66
+ .registerTools([
67
+ // Built-in WDK wallet tools (scoped to 'spark' chain automatically via getChains())
68
+ ...WALLET_TOOLS,
69
+ // Bitfinex pricing: getCurrentPrice, getHistoricalPrice
70
+ ...PRICING_TOOLS,
71
+ ]);
72
+ // -----------------------------------------------------------------------
73
+ // 2. Spark-specific custom tools (Lightning invoices, BTC bridge, MPP)
74
+ // -----------------------------------------------------------------------
75
+ registerSparkTools(server, config.sparkUsdtToken);
76
+ }
77
+ catch (error) {
78
+ process.stderr.write(`[kaleido-mcp] Spark tools disabled (invalid WDK_SEED): ${error}\n`);
79
+ }
80
+ }
81
+ else {
82
+ process.stderr.write('[kaleido-mcp] Spark tools disabled (WDK_SEED not set)\n');
83
+ }
84
+ const sdk = KaleidoClient.create({
85
+ baseUrl: config.kaleidoswapApiUrl,
86
+ nodeUrl: config.rlnNodeUrl,
87
+ });
88
+ // -------------------------------------------------------------------------
89
+ // 3. RLN tools (RGB assets, Lightning channels, atomic swaps)
90
+ // -------------------------------------------------------------------------
91
+ registerRlnTools(server, sdk.rln);
92
+ // -------------------------------------------------------------------------
93
+ // 4. KaleidoSwap DEX tools (quotes, orders, atomic, LSP)
94
+ // -------------------------------------------------------------------------
95
+ registerKaleidoswapTools(server, sdk.maker);
96
+ // -------------------------------------------------------------------------
97
+ // 5. MPP / L402 / 402index.io discovery
98
+ // -------------------------------------------------------------------------
99
+ registerMppTools(server);
100
+ // -------------------------------------------------------------------------
101
+ // 6. Market data (CoinGecko + Fear & Greed)
102
+ // -------------------------------------------------------------------------
103
+ registerMarketTools(server);
104
+ return server;
105
+ }
106
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AACrF,8BAA8B;AAC9B,OAAO,kBAAkB,MAAM,4BAA4B,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAA;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAiB7D,MAAM,UAAU,YAAY,CAAC,MAAwB;IACnD,4EAA4E;IAC5E,uEAAuE;IACvE,4EAA4E;IAC5E,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAA;IAEvD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,IAAI,CAAC;YACH,MAAM;iBACH,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;iBAChC,cAAc,CAAC,OAAO,EAAE,kBAAkB,EAAE;gBAC3C,OAAO,EAAE,MAAM,CAAC,YAAY;gBAC5B,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC/E,CAAC;iBACD,UAAU,EAAE;iBACZ,aAAa,CAAC;gBACb,oFAAoF;gBACpF,GAAG,YAAY;gBACf,wDAAwD;gBACxD,GAAG,aAAa;aACjB,CAAC,CAAA;YAEJ,0EAA0E;YAC1E,uEAAuE;YACvE,0EAA0E;YAC1E,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC,CAAA;QACnD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,0DAA0D,KAAK,IAAI,CAAC,CAAA;QAC3F,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAA;IACjF,CAAC;IAED,MAAM,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC;QAC/B,OAAO,EAAE,MAAM,CAAC,iBAAiB;QACjC,OAAO,EAAE,MAAM,CAAC,UAAU;KAC3B,CAAC,CAAA;IAEF,4EAA4E;IAC5E,8DAA8D;IAC9D,4EAA4E;IAC5E,gBAAgB,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAA;IAEjC,4EAA4E;IAC5E,yDAAyD;IACzD,4EAA4E;IAC5E,wBAAwB,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,CAAA;IAE3C,4EAA4E;IAC5E,wCAAwC;IACxC,4EAA4E;IAC5E,gBAAgB,CAAC,MAAM,CAAC,CAAA;IAExB,4EAA4E;IAC5E,4CAA4C;IAC5C,4EAA4E;IAC5E,mBAAmB,CAAC,MAAM,CAAC,CAAA;IAE3B,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { WdkMcpServer } from '@tetherto/wdk-mcp-toolkit';
2
+ import type { MakerClient } from 'kaleido-sdk';
3
+ export declare function registerKaleidoswapTools(server: WdkMcpServer, maker: MakerClient): void;
@@ -0,0 +1,263 @@
1
+ /**
2
+ * KaleidoSwap DEX tools — quotes, REST orders, atomic HTLC swaps, LSPS1 channels.
3
+ * Ported from kaleidoswap-mcp/src/server.ts and updated for the unified server.
4
+ */
5
+ import { z } from 'zod';
6
+ // In-memory store — persists for process lifetime
7
+ const orderStore = new Map();
8
+ export function registerKaleidoswapTools(server, maker) {
9
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
+ function findAsset(assets, id) {
11
+ return assets.find(a => (a.protocol_ids && Object.values(a.protocol_ids).includes(id)) || a.ticker === id);
12
+ }
13
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
+ async function resolveAsset(id, assets, pairs) {
15
+ const found = findAsset(assets, id);
16
+ if (found)
17
+ return found;
18
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
+ const ps = pairs ?? (await maker.listPairs()).pairs ?? [];
20
+ for (const p of ps) {
21
+ if (p.base.ticker === id || p.base.ticker === id.toUpperCase())
22
+ return { ticker: p.base.ticker, name: p.base.name, precision: p.base.precision };
23
+ if (p.quote.ticker === id || p.quote.ticker === id.toUpperCase())
24
+ return { ticker: p.quote.ticker, name: p.quote.name, precision: p.quote.precision };
25
+ }
26
+ return undefined;
27
+ }
28
+ // -----------------------------------------------------------------------
29
+ server.tool('kaleidoswap_get_assets', 'List all assets tradeable on KaleidoSwap. Returns ticker, name, precision, and RGB protocol ID for each asset.', {}, async () => {
30
+ const { assets } = await maker.listAssets();
31
+ return t(JSON.stringify(assets.map(a => ({
32
+ ticker: a.ticker, name: a.name, precision: a.precision,
33
+ asset_id: a.protocol_ids ? Object.values(a.protocol_ids)[0] : a.ticker,
34
+ protocol_ids: a.protocol_ids ?? {},
35
+ })), null, 2));
36
+ });
37
+ // -----------------------------------------------------------------------
38
+ server.tool('kaleidoswap_get_pairs', 'List all tradeable asset pairs with available layer routes (BTC_LN→RGB_LN, BTC_SPARK→SPARK, etc.).', {}, async () => {
39
+ const { pairs } = await maker.listPairs();
40
+ return t(JSON.stringify(pairs.map(p => ({
41
+ base: { ticker: p.base.ticker, name: p.base.name, precision: p.base.precision },
42
+ quote: { ticker: p.quote.ticker, name: p.quote.name, precision: p.quote.precision },
43
+ routes: p.routes ?? [],
44
+ })), null, 2));
45
+ });
46
+ // -----------------------------------------------------------------------
47
+ server.tool('kaleidoswap_get_quote', 'Get a price quote for a swap. Returns expected output amount, price, fee, and rfq_id (use in kaleidoswap_place_order or kaleidoswap_atomic_init). Quote expires in ~60s.', {
48
+ from_asset_id: z.string().describe("Asset to sell — ticker ('BTC') or RGB protocol ID ('rgb:...')"),
49
+ to_asset_id: z.string().describe('Asset to buy'),
50
+ from_layer: z.string().describe("Source layer: 'BTC_LN', 'BTC_SPARK', 'RGB_LN'"),
51
+ to_layer: z.string().describe("Destination layer: 'RGB_LN', 'BTC_SPARK', 'BTC_LN'"),
52
+ from_amount: z.number().positive().describe('Amount to sell in display units (e.g. 0.001 BTC, 100.0 USDT)'),
53
+ }, async ({ from_asset_id, to_asset_id, from_layer, to_layer, from_amount }) => {
54
+ const [{ assets }, { pairs }] = await Promise.all([maker.listAssets(), maker.listPairs()]);
55
+ const fromAsset = await resolveAsset(from_asset_id, assets, pairs);
56
+ if (!fromAsset)
57
+ throw new Error(`Unknown asset: ${from_asset_id}`);
58
+ const rawAmount = maker.toRaw(from_amount, fromAsset.precision);
59
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
60
+ const quote = await maker.getQuote({ from_asset: { asset_id: from_asset_id, layer: from_layer, amount: rawAmount }, to_asset: { asset_id: to_asset_id, layer: to_layer } });
61
+ const toAsset = await resolveAsset(to_asset_id, assets, pairs);
62
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
63
+ const toPrecision = toAsset?.precision ?? quote.to_asset.precision;
64
+ return t(JSON.stringify({
65
+ rfq_id: quote.rfq_id,
66
+ from_asset: { asset_id: from_asset_id, ticker: quote.from_asset.ticker, layer: quote.from_asset.layer, amount_raw: quote.from_asset.amount, amount_display: maker.toDisplay(quote.from_asset.amount, fromAsset.precision) },
67
+ to_asset: { asset_id: to_asset_id, ticker: quote.to_asset.ticker, layer: quote.to_asset.layer, amount_raw: quote.to_asset.amount, amount_display: maker.toDisplay(quote.to_asset.amount, toPrecision) },
68
+ price: quote.price,
69
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
70
+ fee_base: quote.fee?.base_fee ?? 0,
71
+ expires_at: new Date(quote.expires_at * 1000).toISOString(),
72
+ }, null, 2));
73
+ });
74
+ // -----------------------------------------------------------------------
75
+ server.tool('kaleidoswap_get_spreads', 'Get quotes across all available routes for a pair. Detects cross-protocol arbitrage. A spread > 0.5% between routes is actionable.', {
76
+ from_asset_id: z.string(), to_asset_id: z.string(),
77
+ from_amount: z.number().positive().describe('Amount to sell in display units'),
78
+ }, async ({ from_asset_id, to_asset_id, from_amount }) => {
79
+ const [{ assets }, { pairs }] = await Promise.all([maker.listAssets(), maker.listPairs()]);
80
+ const fromAsset = await resolveAsset(from_asset_id, assets, pairs);
81
+ const toAsset = await resolveAsset(to_asset_id, assets, pairs);
82
+ if (!fromAsset)
83
+ throw new Error(`Unknown asset: ${from_asset_id}`);
84
+ const toPrecision = toAsset?.precision ?? 8;
85
+ const rawAmount = maker.toRaw(from_amount, fromAsset.precision);
86
+ const routes = [];
87
+ for (const p of pairs) {
88
+ const bId = p.base.protocol_ids ? Object.values(p.base.protocol_ids)[0] : p.base.ticker;
89
+ const qId = p.quote.protocol_ids ? Object.values(p.quote.protocol_ids)[0] : p.quote.ticker;
90
+ if ((bId === from_asset_id || p.base.ticker === from_asset_id) && (qId === to_asset_id || p.quote.ticker === to_asset_id) && p.routes)
91
+ routes.push(...p.routes);
92
+ }
93
+ if (routes.length === 0)
94
+ return t(`No routes found for ${from_asset_id} → ${to_asset_id}`);
95
+ const results = await Promise.allSettled(routes.map(async (r) => {
96
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
97
+ const q = await maker.getQuote({ from_asset: { asset_id: from_asset_id, layer: r.from_layer, amount: rawAmount }, to_asset: { asset_id: to_asset_id, layer: r.to_layer } });
98
+ return { route: `${r.from_layer}→${r.to_layer}`, price: q.price, to_amount_display: maker.toDisplay(q.to_asset.amount, toPrecision), expires_at: new Date(q.expires_at * 1000).toISOString() };
99
+ }));
100
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
101
+ const quotes = results.filter((r) => r.status === 'fulfilled').map(r => r.value).sort((a, b) => b.to_amount_display - a.to_amount_display);
102
+ if (quotes.length < 2)
103
+ return t(JSON.stringify({ quotes, arb_opportunity: false }, null, 2));
104
+ const spreadPct = ((quotes[0].to_amount_display - quotes[quotes.length - 1].to_amount_display) / quotes[quotes.length - 1].to_amount_display) * 100;
105
+ return t(JSON.stringify({ quotes, best_route: quotes[0].route, spread_pct: spreadPct.toFixed(4), arb_opportunity: spreadPct >= 0.5 }, null, 2));
106
+ });
107
+ // -----------------------------------------------------------------------
108
+ server.tool('kaleidoswap_place_order', 'Place a REST swap order on KaleidoSwap. Returns a deposit_address — send the exact from_amount to it to complete the swap.', {
109
+ from_asset_id: z.string(), to_asset_id: z.string(),
110
+ from_layer: z.string().describe("Source layer: 'BTC_LN', 'BTC_SPARK', 'RGB_LN'"),
111
+ to_layer: z.string().describe("Destination layer: 'RGB_LN', 'BTC_LN', 'BTC_SPARK'"),
112
+ from_amount: z.number().positive().describe('Amount to sell in display units'),
113
+ receiver_address: z.string().describe('Address where output asset is delivered (RGB invoice, BOLT11, Spark address, etc.)'),
114
+ receiver_address_format: z.string().describe("'RGB_INVOICE', 'BOLT11', 'BTC_ADDRESS', 'SPARK_ADDRESS'"),
115
+ }, async ({ from_asset_id, to_asset_id, from_layer, to_layer, from_amount, receiver_address, receiver_address_format }) => {
116
+ const { assets } = await maker.listAssets();
117
+ const fromAsset = findAsset(assets, from_asset_id);
118
+ const toAsset = findAsset(assets, to_asset_id);
119
+ if (!fromAsset)
120
+ throw new Error(`Unknown asset: ${from_asset_id}`);
121
+ if (!toAsset)
122
+ throw new Error(`Unknown asset: ${to_asset_id}`);
123
+ const rawAmount = maker.toRaw(from_amount, fromAsset.precision);
124
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
125
+ const quote = await maker.getQuote({ from_asset: { asset_id: from_asset_id, layer: from_layer, amount: rawAmount }, to_asset: { asset_id: to_asset_id, layer: to_layer } });
126
+ const order = await maker.createSwapOrder({
127
+ rfq_id: quote.rfq_id,
128
+ from_asset: { asset_id: quote.from_asset.asset_id, name: quote.from_asset.name, ticker: quote.from_asset.ticker, layer: quote.from_asset.layer, amount: quote.from_asset.amount, precision: fromAsset.precision },
129
+ to_asset: { asset_id: quote.to_asset.asset_id, name: quote.to_asset.name, ticker: quote.to_asset.ticker, layer: quote.to_asset.layer, amount: quote.to_asset.amount, precision: toAsset.precision },
130
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
131
+ receiver_address: { address: receiver_address, format: receiver_address_format },
132
+ min_onchain_conf: 1,
133
+ });
134
+ const fromDisplay = maker.toDisplay(quote.from_asset.amount, fromAsset.precision);
135
+ const toDisplay = maker.toDisplay(quote.to_asset.amount, toAsset.precision);
136
+ const tracked = { orderId: order.id, fromAssetId: from_asset_id, toAssetId: to_asset_id, fromLayer: from_layer, toLayer: to_layer, fromAmount: fromDisplay, toAmount: toDisplay, depositAddress: order.deposit_address?.address ?? null, depositAddressFormat: order.deposit_address?.format ?? null, receiverAddress: receiver_address, status: order.status, placedAt: new Date().toISOString() };
137
+ orderStore.set(order.id, tracked);
138
+ return t(JSON.stringify({ order_id: order.id, status: order.status, deposit_address: order.deposit_address?.address ?? null, deposit_address_format: order.deposit_address?.format ?? null, from_amount: fromDisplay, to_amount: toDisplay, from_ticker: fromAsset.ticker, to_ticker: toAsset.ticker, instruction: `Send ${fromDisplay} ${fromAsset.ticker} to deposit_address to complete swap` }, null, 2));
139
+ });
140
+ // -----------------------------------------------------------------------
141
+ server.tool('kaleidoswap_get_order_status', 'Check current status of a swap order. Status: PENDING → PROCESSING → FILLED | FAILED | EXPIRED | CANCELLED.', { order_id: z.string() }, async ({ order_id }) => {
142
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
143
+ const { order } = await maker.getSwapOrderStatus({ order_id });
144
+ const tracked = orderStore.get(order_id);
145
+ if (tracked && order) {
146
+ tracked.status = order.status;
147
+ orderStore.set(order_id, tracked);
148
+ }
149
+ return t(JSON.stringify({ order_id: order?.id, status: order?.status, from_asset: order?.from_asset ? { ticker: order.from_asset.ticker, layer: order.from_asset.layer, amount_display: order.from_asset.amount / Math.pow(10, order.from_asset.precision) } : null, to_asset: order?.to_asset ? { ticker: order.to_asset.ticker, layer: order.to_asset.layer, amount_display: order.to_asset.amount / Math.pow(10, order.to_asset.precision) } : null, deposit_address: order?.deposit_address?.address ?? null }, null, 2));
150
+ });
151
+ // -----------------------------------------------------------------------
152
+ server.tool('kaleidoswap_get_open_orders', 'List swap orders placed in this session with last known status.', { status_filter: z.enum(['all', 'pending', 'active', 'completed']).optional().describe("'pending'=active, 'completed'=terminal, 'all'=default") }, async ({ status_filter = 'all' }) => {
153
+ let orders = Array.from(orderStore.values());
154
+ if (status_filter === 'pending' || status_filter === 'active')
155
+ orders = orders.filter(o => ['PENDING', 'PROCESSING'].includes(o.status));
156
+ else if (status_filter === 'completed')
157
+ orders = orders.filter(o => ['FILLED', 'FAILED', 'EXPIRED', 'CANCELLED'].includes(o.status));
158
+ return t(JSON.stringify(orders, null, 2));
159
+ });
160
+ // -----------------------------------------------------------------------
161
+ server.tool('kaleidoswap_cancel_order', 'Mark an order as cancelled in the local session tracker. Orders without a deposit expire automatically on the server.', { order_id: z.string() }, async ({ order_id }) => {
162
+ const tracked = orderStore.get(order_id);
163
+ if (!tracked)
164
+ return t(JSON.stringify({ error: `Order ${order_id} not found in session` }));
165
+ tracked.status = 'CANCELLED';
166
+ orderStore.set(order_id, tracked);
167
+ return t(JSON.stringify({ order_id, cancelled: true, status: 'CANCELLED' }, null, 2));
168
+ });
169
+ // -----------------------------------------------------------------------
170
+ server.tool('kaleidoswap_get_position', 'Session trading stats: total orders, fill rate, volume by asset.', {}, async () => {
171
+ const orders = Array.from(orderStore.values());
172
+ if (orders.length === 0)
173
+ return t(JSON.stringify({ message: 'No orders in session', orders: 0 }));
174
+ const byAsset = {};
175
+ for (const o of orders) {
176
+ if (o.status === 'FILLED') {
177
+ if (!byAsset[o.fromAssetId])
178
+ byAsset[o.fromAssetId] = { sold: 0, bought: 0, ticker: o.fromAssetId };
179
+ if (!byAsset[o.toAssetId])
180
+ byAsset[o.toAssetId] = { sold: 0, bought: 0, ticker: o.toAssetId };
181
+ byAsset[o.fromAssetId].sold += o.fromAmount;
182
+ byAsset[o.toAssetId].bought += o.toAmount;
183
+ }
184
+ }
185
+ const total = orders.length, filled = orders.filter(o => o.status === 'FILLED').length;
186
+ const pending = orders.filter(o => ['PENDING', 'PROCESSING'].includes(o.status)).length;
187
+ const failed = orders.filter(o => ['FAILED', 'EXPIRED', 'CANCELLED'].includes(o.status)).length;
188
+ return t(JSON.stringify({ session_summary: { total_orders: total, filled, pending, failed, fill_rate_pct: total > 0 ? ((filled / total) * 100).toFixed(1) : '0.0' }, volume_by_asset: Object.values(byAsset), orders: orders.slice(-10) }, null, 2));
189
+ });
190
+ // -----------------------------------------------------------------------
191
+ server.tool('kaleidoswap_atomic_init', 'Step 1 of atomic HTLC swap: initiate on KaleidoSwap. Returns swapstring and payment_hash. Use raw integer amounts from quote.from_asset.amount_raw / quote.to_asset.amount_raw.', {
192
+ rfq_id: z.string(), from_asset_id: z.string(),
193
+ from_amount_raw: z.number().int().positive().describe('Raw integer units from quote'),
194
+ to_asset_id: z.string(),
195
+ to_amount_raw: z.number().int().positive().describe('Raw integer units from quote'),
196
+ },
197
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
198
+ async ({ rfq_id, from_asset_id, from_amount_raw, to_asset_id, to_amount_raw }) => t(JSON.stringify(await maker.initSwap({ rfq_id, from_asset: from_asset_id, from_amount: from_amount_raw, to_asset: to_asset_id, to_amount: to_amount_raw }), null, 2)));
199
+ // -----------------------------------------------------------------------
200
+ server.tool('kaleidoswap_atomic_execute', 'Step 3 of atomic swap: confirm execution after rln_atomic_taker has whitelisted the HTLC. Provide swapstring, payment_hash from kaleidoswap_atomic_init, plus taker_pubkey from rln_get_node_info.', { swapstring: z.string(), taker_pubkey: z.string().describe('Node pubkey from rln_get_node_info'), payment_hash: z.string() },
201
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
202
+ async ({ swapstring, taker_pubkey, payment_hash }) => t(JSON.stringify(await maker.executeSwap({ swapstring, taker_pubkey, payment_hash }), null, 2)));
203
+ // -----------------------------------------------------------------------
204
+ server.tool('kaleidoswap_atomic_status', 'Poll atomic swap status by payment_hash. Status: Waiting → Pending → Succeeded | Expired | Failed.', { payment_hash: z.string() }, async ({ payment_hash }) => t(JSON.stringify(await maker.getAtomicSwapStatus({ payment_hash }), null, 2)));
205
+ // -----------------------------------------------------------------------
206
+ server.tool('kaleidoswap_lsp_get_info', 'Get LSP peer connection info and channel capacity limits. Call first to get lsp_connection_url for rln_connect_peer.', {}, async () => {
207
+ const info = await maker.getLspInfo();
208
+ return t(JSON.stringify({ lsp_connection_url: info.lsp_connection_url, options: { min_channel_balance_sat: info.options.min_channel_balance_sat, max_channel_balance_sat: info.options.max_channel_balance_sat, max_channel_expiry_blocks: info.options.max_channel_expiry_blocks }, assets: info.assets.map(a => ({ ticker: a.ticker, asset_id: a.asset_id })), instruction: 'Use lsp_connection_url with rln_connect_peer before kaleidoswap_lsp_create_order' }, null, 2));
209
+ });
210
+ // -----------------------------------------------------------------------
211
+ server.tool('kaleidoswap_lsp_estimate_fees', 'Estimate LSPS1 channel opening fees (setup, capacity, duration, total). Call before kaleidoswap_lsp_create_order.', {
212
+ client_pubkey: z.string(), lsp_balance_sat: z.number().int().positive(),
213
+ client_balance_sat: z.number().int().min(0), channel_expiry_blocks: z.number().int().positive(),
214
+ required_channel_confirmations: z.number().int().min(0).optional(),
215
+ funding_confirms_within_blocks: z.number().int().positive().optional(),
216
+ asset_id: z.string().optional(), lsp_asset_amount: z.number().optional(), rfq_id: z.string().optional(),
217
+ }, async ({ client_pubkey, lsp_balance_sat, client_balance_sat, channel_expiry_blocks, required_channel_confirmations, funding_confirms_within_blocks, asset_id, lsp_asset_amount, rfq_id }) => {
218
+ const body = { client_pubkey, lsp_balance_sat, client_balance_sat, channel_expiry_blocks, required_channel_confirmations: required_channel_confirmations ?? 0, funding_confirms_within_blocks: funding_confirms_within_blocks ?? 6 };
219
+ if (asset_id)
220
+ body.asset_id = asset_id;
221
+ if (lsp_asset_amount !== undefined)
222
+ body.lsp_asset_amount = lsp_asset_amount;
223
+ if (rfq_id)
224
+ body.rfq_id = rfq_id;
225
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
226
+ return t(JSON.stringify(await maker.estimateLspFees(body), null, 2));
227
+ });
228
+ // -----------------------------------------------------------------------
229
+ server.tool('kaleidoswap_lsp_create_order', 'Request a new Lightning channel from KaleidoSwap LSP (LSPS1). Returns order_id and bolt11_invoice to pay. Poll kaleidoswap_lsp_get_order until COMPLETED.', {
230
+ client_pubkey: z.string(), lsp_balance_sat: z.number().int().positive(),
231
+ client_balance_sat: z.number().int().min(0),
232
+ required_channel_confirmations: z.number().int().min(0).describe('0 for zero-conf'),
233
+ funding_confirms_within_blocks: z.number().int().positive(),
234
+ channel_expiry_blocks: z.number().int().positive(),
235
+ announce_channel: z.boolean(),
236
+ asset_id: z.string().optional(), lsp_asset_amount: z.number().optional(),
237
+ client_asset_amount: z.number().optional(), rfq_id: z.string().optional(),
238
+ }, async ({ client_pubkey, lsp_balance_sat, client_balance_sat, required_channel_confirmations, funding_confirms_within_blocks, channel_expiry_blocks, announce_channel, asset_id, lsp_asset_amount, client_asset_amount, rfq_id }) => {
239
+ const body = { client_pubkey, lsp_balance_sat, client_balance_sat, required_channel_confirmations, funding_confirms_within_blocks, channel_expiry_blocks, announce_channel };
240
+ if (asset_id)
241
+ body.asset_id = asset_id;
242
+ if (lsp_asset_amount !== undefined)
243
+ body.lsp_asset_amount = lsp_asset_amount;
244
+ if (client_asset_amount !== undefined)
245
+ body.client_asset_amount = client_asset_amount;
246
+ if (rfq_id)
247
+ body.rfq_id = rfq_id;
248
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
249
+ const order = await maker.createLspOrder(body);
250
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
251
+ const payment = order.payment;
252
+ const bolt11 = payment?.bolt11?.invoice ?? payment?.bolt11_invoice ?? null;
253
+ const onchain_address = payment?.onchain?.address ?? payment?.onchain_address ?? null;
254
+ const onchain_amount_sat = payment?.onchain?.fee_total_sat ?? payment?.onchain?.order_total_sat ?? null;
255
+ return t(JSON.stringify({ order_id: order.order_id, order_state: order.order_state, bolt11_invoice: bolt11, onchain_address, onchain_amount_sat, fee_total_sat: payment?.bolt11?.fee_total_sat ?? payment?.fee_total_sat ?? null, order_total_sat: payment?.bolt11?.order_total_sat ?? payment?.order_total_sat ?? null, instruction: 'Pay via rln_pay_invoice (Lightning). If Lightning fails (no channels), use rln_send_btc with onchain_address. Never use spark_pay_lightning_invoice for LSP orders. Poll with kaleidoswap_lsp_get_order.' }, null, 2));
256
+ });
257
+ // -----------------------------------------------------------------------
258
+ server.tool('kaleidoswap_lsp_get_order', 'Poll LSPS1 channel order status. States: CREATED → PENDING_RATE_DECISION → CHANNEL_OPENING → COMPLETED | FAILED.', { order_id: z.string() },
259
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
260
+ async ({ order_id }) => t(JSON.stringify(await maker.getLspOrder({ order_id }), null, 2)));
261
+ }
262
+ const t = (content) => ({ content: [{ type: 'text', text: content }] });
263
+ //# sourceMappingURL=kaleidoswap-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kaleidoswap-tools.js","sourceRoot":"","sources":["../../src/tools/kaleidoswap-tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { WdkMcpServer } from '@tetherto/wdk-mcp-toolkit';
2
+ export declare function registerMarketTools(server: WdkMcpServer): void;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Market data tools — CoinGecko prices, OHLCV, Fear & Greed sentiment.
3
+ * Note: WDK PRICING_TOOLS (Bitfinex) are registered separately via registerTools().
4
+ * These are additional CoinGecko-sourced tools with extra metadata.
5
+ */
6
+ import { z } from 'zod';
7
+ import { MarketClient } from '../clients/market-client.js';
8
+ export function registerMarketTools(server) {
9
+ const market = new MarketClient();
10
+ const registerAliases = (names, description, schema,
11
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
+ handler) => {
13
+ for (const name of names)
14
+ server.tool(name, description, schema, handler);
15
+ };
16
+ // -----------------------------------------------------------------------
17
+ registerAliases(['l402_get_price', 'get_price'], 'Get current spot price and 24h stats for an asset (BTC, USDT, XAUT, ETH) in USD or other currency. Use before placing swaps to know the market rate.', {
18
+ asset: z.enum(['BTC', 'USDT', 'XAUT', 'ETH']),
19
+ vs_currency: z.enum(['usd', 'eur', 'btc', 'sats']).optional().describe('Quote currency (default: usd)'),
20
+ }, async ({ asset, vs_currency = 'usd' }) => {
21
+ const queryCurrency = vs_currency === 'sats' ? 'btc' : vs_currency;
22
+ const result = await market.getPrice(asset, queryCurrency);
23
+ if (vs_currency === 'sats' && result.price) {
24
+ result.price = Math.round(result.price * 1e8);
25
+ result.vs_currency = 'SATS';
26
+ }
27
+ return t(JSON.stringify(result, null, 2));
28
+ });
29
+ // -----------------------------------------------------------------------
30
+ registerAliases(['l402_get_market_data', 'get_market_data'], 'Get spot prices and 24h stats for multiple assets in one call.', { assets: z.array(z.enum(['BTC', 'USDT', 'XAUT', 'ETH'])).min(1).max(4) }, async ({ assets }) => t(JSON.stringify(await market.getMarketData(assets), null, 2)));
31
+ // -----------------------------------------------------------------------
32
+ registerAliases(['l402_get_ohlcv', 'get_ohlcv'], 'Get OHLCV candle data for an asset over the last N days. Use to detect price trends.', {
33
+ asset: z.enum(['BTC', 'USDT', 'XAUT', 'ETH']),
34
+ days: z.number().int().min(1).max(90).optional().describe('Days of candles (default: 1, max: 90)'),
35
+ }, async ({ asset, days = 1 }) => {
36
+ const candles = await market.getOhlcv(asset, days);
37
+ const latest = candles[candles.length - 1], oldest = candles[0];
38
+ const pctChange = oldest && latest ? (((latest.close - oldest.open) / oldest.open) * 100).toFixed(2) : null;
39
+ return t(JSON.stringify({ asset, days, candle_count: candles.length, period_change_pct: pctChange ? parseFloat(pctChange) : null, latest_close: latest?.close ?? null, candles: candles.slice(-20) }, null, 2));
40
+ });
41
+ // -----------------------------------------------------------------------
42
+ registerAliases(['l402_get_sentiment', 'get_sentiment'], 'Get the Crypto Fear & Greed Index (0–100). Below 25 = extreme fear (buy signal). Above 75 = extreme greed (sell signal). Use as directional signal when deciding swap direction.', {}, async () => {
43
+ const sentiment = await market.getFearGreedIndex();
44
+ const signal = sentiment.index_value < 25 ? 'STRONG_BUY' : sentiment.index_value < 40 ? 'BUY' : sentiment.index_value > 75 ? 'STRONG_SELL' : sentiment.index_value > 60 ? 'SELL' : 'NEUTRAL';
45
+ return t(JSON.stringify({ ...sentiment, trading_signal: signal }, null, 2));
46
+ });
47
+ }
48
+ const t = (content) => ({ content: [{ type: 'text', text: content }] });
49
+ //# sourceMappingURL=market-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"market-tools.js","sourceRoot":"","sources":["../../src/tools/market-tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { WdkMcpServer } from '@tetherto/wdk-mcp-toolkit';
2
+ export declare function registerMppTools(server: WdkMcpServer): void;