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/LICENSE +17 -0
- package/README.md +55 -0
- package/dist/clients/market-client.d.ts +33 -0
- package/dist/clients/market-client.js +72 -0
- package/dist/clients/market-client.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.js +80 -0
- package/dist/index.js.map +1 -0
- package/dist/mpp-client.d.ts +80 -0
- package/dist/mpp-client.js +186 -0
- package/dist/mpp-client.js.map +1 -0
- package/dist/server.d.ts +58 -0
- package/dist/server.js +106 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/kaleidoswap-tools.d.ts +3 -0
- package/dist/tools/kaleidoswap-tools.js +263 -0
- package/dist/tools/kaleidoswap-tools.js.map +1 -0
- package/dist/tools/market-tools.d.ts +2 -0
- package/dist/tools/market-tools.js +49 -0
- package/dist/tools/market-tools.js.map +1 -0
- package/dist/tools/mpp-tools.d.ts +2 -0
- package/dist/tools/mpp-tools.js +133 -0
- package/dist/tools/mpp-tools.js.map +1 -0
- package/dist/tools/rln-tools.d.ts +3 -0
- package/dist/tools/rln-tools.js +245 -0
- package/dist/tools/rln-tools.js.map +1 -0
- package/dist/tools/spark-tools.d.ts +2 -0
- package/dist/tools/spark-tools.js +218 -0
- package/dist/tools/spark-tools.js.map +1 -0
- package/package.json +51 -0
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,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,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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"}
|