dexbot 1.4.20 → 1.4.21
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/CHANGELOG.md +23 -0
- package/README.md +22 -12
- package/analysis/ama_fitting/calibrate_convergence_er.ts +1 -1
- package/analysis/ama_fitting/package.json +1 -1
- package/analysis/bot_fitting/shared_utils.ts +1 -1
- package/analysis/bot_key_utils.ts +1 -5
- package/analysis/bot_usage/kibana_bot_queries.ts +1 -256
- package/analysis/chart_css.ts +1 -1
- package/analysis/math_utils.ts +1 -8
- package/analysis/trend_detection/package.json +1 -1
- package/claw/ecosystem.config.cjs +2 -3
- package/claw/examples/memu_integration_example.ts +17 -17
- package/claw/modules/chain_actions.ts +51 -54
- package/claw/modules/chain_broadcast.ts +66 -104
- package/claw/modules/claw_bridge.ts +60 -80
- package/claw/modules/claw_catalog.ts +47 -16
- package/claw/modules/claw_infra.ts +1 -5
- package/claw/modules/claw_launcher.ts +47 -49
- package/claw/modules/claw_skill_md.ts +8 -11
- package/claw/modules/credit_runtime_adapter.ts +2 -18
- package/claw/modules/decision_loop.ts +4 -0
- package/claw/modules/dexbot_bridge.ts +1 -1
- package/claw/modules/dexbot_profiles.ts +5 -21
- package/claw/modules/honest_ecosystem.ts +24 -8
- package/claw/modules/liquidity_pools.ts +10 -3
- package/claw/modules/mcp_utils.ts +109 -0
- package/claw/modules/memu_bridge.ts +76 -54
- package/claw/modules/mpa_utils.ts +26 -3
- package/claw/modules/position_discovery.ts +16 -27
- package/claw/modules/position_manager.ts +32 -41
- package/claw/modules/position_manager_watch.ts +3 -2
- package/claw/modules/short_mpa_strategy.ts +1 -9
- package/claw/modules/skill_utils.ts +5 -3
- package/claw/modules/utils.ts +9 -1
- package/claw/package.json +1 -1
- package/claw/runtimes/openclaw-plugin/index.ts +27 -10
- package/claw/runtimes/openclaw-plugin/openclaw.plugin.json +1 -1
- package/claw/runtimes/openclaw-plugin/package.json +1 -1
- package/claw/scripts/claw_bridge.ts +1 -1
- package/claw/scripts/claw_mcp_server.ts +19 -78
- package/claw/scripts/honest_assets_report.ts +19 -84
- package/claw/scripts/memu_mcp_server.ts +57 -155
- package/claw/tests/test_claw_bridge.ts +6 -2
- package/claw/tests/test_claw_mcp_transport.ts +2 -2
- package/dist/analysis/ama_fitting/calibrate_convergence_er.js +1 -1
- package/dist/analysis/ama_fitting/calibrate_convergence_er.js.map +1 -1
- package/dist/analysis/bot_fitting/shared_utils.d.ts +1 -12
- package/dist/analysis/bot_fitting/shared_utils.d.ts.map +1 -1
- package/dist/analysis/bot_fitting/shared_utils.js +1 -1
- package/dist/analysis/bot_fitting/shared_utils.js.map +1 -1
- package/dist/analysis/bot_key_utils.d.ts +1 -1
- package/dist/analysis/bot_key_utils.d.ts.map +1 -1
- package/dist/analysis/bot_key_utils.js +1 -5
- package/dist/analysis/bot_key_utils.js.map +1 -1
- package/dist/analysis/bot_usage/kibana_bot_queries.d.ts +1 -337
- package/dist/analysis/bot_usage/kibana_bot_queries.d.ts.map +1 -1
- package/dist/analysis/bot_usage/kibana_bot_queries.js +1 -241
- package/dist/analysis/bot_usage/kibana_bot_queries.js.map +1 -1
- package/dist/analysis/chart_css.d.ts +1 -15
- package/dist/analysis/chart_css.d.ts.map +1 -1
- package/dist/analysis/chart_css.js +1 -1
- package/dist/analysis/chart_css.js.map +1 -1
- package/dist/analysis/math_utils.d.ts +3 -5
- package/dist/analysis/math_utils.d.ts.map +1 -1
- package/dist/analysis/math_utils.js +3 -5
- package/dist/analysis/math_utils.js.map +1 -1
- package/dist/bot.js +2 -2
- package/dist/bot.js.map +1 -1
- package/dist/credential-daemon.js +1 -1
- package/dist/credential-daemon.js.map +1 -1
- package/dist/dexbot.d.ts.map +1 -1
- package/dist/dexbot.js +18 -14
- package/dist/dexbot.js.map +1 -1
- package/dist/market_adapter/ama_signal_runner.js +3 -3
- package/dist/market_adapter/core/kibana_client.d.ts +1 -3
- package/dist/market_adapter/core/kibana_client.d.ts.map +1 -1
- package/dist/market_adapter/core/kibana_client.js +1 -1
- package/dist/market_adapter/core/kibana_client.js.map +1 -1
- package/dist/market_adapter/core/market_adapter_service.d.ts +1 -2
- package/dist/market_adapter/core/market_adapter_service.d.ts.map +1 -1
- package/dist/market_adapter/core/market_adapter_service.js +1 -1
- package/dist/market_adapter/core/market_adapter_service.js.map +1 -1
- package/dist/market_adapter/core/strategies/regime_gate.d.ts +1 -2
- package/dist/market_adapter/core/strategies/regime_gate.d.ts.map +1 -1
- package/dist/market_adapter/core/strategies/regime_gate.js +1 -1
- package/dist/market_adapter/core/strategies/regime_gate.js.map +1 -1
- package/dist/market_adapter/inputs/fetch_cex_synthetic_data.js +2 -2
- package/dist/market_adapter/inputs/fetch_cex_synthetic_data.js.map +1 -1
- package/dist/market_adapter/inputs/fetch_lp_data.d.ts +5 -5
- package/dist/market_adapter/inputs/fetch_lp_data.js +5 -5
- package/dist/market_adapter/inputs/kibana_source.d.ts +1 -2
- package/dist/market_adapter/inputs/kibana_source.d.ts.map +1 -1
- package/dist/market_adapter/inputs/kibana_source.js +1 -1
- package/dist/market_adapter/inputs/kibana_source.js.map +1 -1
- package/dist/market_adapter/lp_chart_strategy_loader.d.ts +1 -2
- package/dist/market_adapter/lp_chart_strategy_loader.d.ts.map +1 -1
- package/dist/market_adapter/lp_chart_strategy_loader.js +4 -4
- package/dist/market_adapter/lp_chart_strategy_loader.js.map +1 -1
- package/dist/market_adapter/market_adapter.d.ts.map +1 -1
- package/dist/market_adapter/market_adapter.js +2 -1
- package/dist/market_adapter/market_adapter.js.map +1 -1
- package/dist/modules/account_bots.d.ts +3 -0
- package/dist/modules/account_bots.d.ts.map +1 -1
- package/dist/modules/account_bots.js +156 -46
- package/dist/modules/account_bots.js.map +1 -1
- package/dist/modules/account_orders.d.ts +1 -7
- package/dist/modules/account_orders.d.ts.map +1 -1
- package/dist/modules/account_orders.js +9 -17
- package/dist/modules/account_orders.js.map +1 -1
- package/dist/modules/bitshares_client.d.ts +2 -14
- package/dist/modules/bitshares_client.d.ts.map +1 -1
- package/dist/modules/bitshares_client.js +22 -31
- package/dist/modules/bitshares_client.js.map +1 -1
- package/dist/modules/bot_settings.js +1 -1
- package/dist/modules/bot_settings.js.map +1 -1
- package/dist/modules/chain_keys.js +2 -2
- package/dist/modules/chain_keys.js.map +1 -1
- package/dist/modules/chain_orders.d.ts +2 -3
- package/dist/modules/chain_orders.d.ts.map +1 -1
- package/dist/modules/chain_orders.js +8 -25
- package/dist/modules/chain_orders.js.map +1 -1
- package/dist/modules/config.d.ts.map +1 -1
- package/dist/modules/config.js +4 -1
- package/dist/modules/config.js.map +1 -1
- package/dist/modules/constants.d.ts +0 -1
- package/dist/modules/constants.d.ts.map +1 -1
- package/dist/modules/constants.js +0 -4
- package/dist/modules/constants.js.map +1 -1
- package/dist/modules/credential_policy.js +1 -1
- package/dist/modules/credential_policy.js.map +1 -1
- package/dist/modules/dexbot_class.d.ts.map +1 -1
- package/dist/modules/dexbot_class.js +3 -2
- package/dist/modules/dexbot_class.js.map +1 -1
- package/dist/modules/dexbot_state_recovery.d.ts.map +1 -1
- package/dist/modules/dexbot_state_recovery.js +2 -1
- package/dist/modules/dexbot_state_recovery.js.map +1 -1
- package/dist/modules/fund_registry.d.ts.map +1 -1
- package/dist/modules/fund_registry.js +5 -2
- package/dist/modules/fund_registry.js.map +1 -1
- package/dist/modules/launcher/bot_supervisor.d.ts.map +1 -1
- package/dist/modules/launcher/bot_supervisor.js +6 -7
- package/dist/modules/launcher/bot_supervisor.js.map +1 -1
- package/dist/modules/launcher/foreign_cred_daemon.d.ts.map +1 -1
- package/dist/modules/launcher/foreign_cred_daemon.js +6 -0
- package/dist/modules/launcher/foreign_cred_daemon.js.map +1 -1
- package/dist/modules/launcher/market_adapter_runtime.d.ts +2 -3
- package/dist/modules/launcher/market_adapter_runtime.d.ts.map +1 -1
- package/dist/modules/launcher/market_adapter_runtime.js +7 -15
- package/dist/modules/launcher/market_adapter_runtime.js.map +1 -1
- package/dist/modules/launcher/monolithic_runtime.d.ts.map +1 -1
- package/dist/modules/launcher/monolithic_runtime.js +1 -0
- package/dist/modules/launcher/monolithic_runtime.js.map +1 -1
- package/dist/modules/launcher/status_reporting.d.ts +1 -2
- package/dist/modules/launcher/status_reporting.d.ts.map +1 -1
- package/dist/modules/launcher/status_reporting.js +1 -4
- package/dist/modules/launcher/status_reporting.js.map +1 -1
- package/dist/modules/order/accounting.js +2 -2
- package/dist/modules/order/accounting.js.map +1 -1
- package/dist/modules/order/format.d.ts +0 -8
- package/dist/modules/order/format.d.ts.map +1 -1
- package/dist/modules/order/format.js +0 -8
- package/dist/modules/order/format.js.map +1 -1
- package/dist/modules/order/logger.js +1 -1
- package/dist/modules/order/logger.js.map +1 -1
- package/dist/modules/order/logger_state.d.ts +1 -13
- package/dist/modules/order/logger_state.d.ts.map +1 -1
- package/dist/modules/order/logger_state.js +1 -11
- package/dist/modules/order/logger_state.js.map +1 -1
- package/dist/modules/order/processed_fill_store.d.ts +0 -5
- package/dist/modules/order/processed_fill_store.d.ts.map +1 -1
- package/dist/modules/order/processed_fill_store.js +1 -12
- package/dist/modules/order/processed_fill_store.js.map +1 -1
- package/dist/modules/order/sync_engine.d.ts.map +1 -1
- package/dist/modules/order/sync_engine.js +10 -3
- package/dist/modules/order/sync_engine.js.map +1 -1
- package/dist/modules/order/utils/math.d.ts +7 -1
- package/dist/modules/order/utils/math.d.ts.map +1 -1
- package/dist/modules/order/utils/math.js +19 -1
- package/dist/modules/order/utils/math.js.map +1 -1
- package/dist/modules/order/utils/order.d.ts.map +1 -1
- package/dist/modules/order/utils/order.js +10 -2
- package/dist/modules/order/utils/order.js.map +1 -1
- package/dist/modules/runtime_settings.js +3 -1
- package/dist/modules/runtime_settings.js.map +1 -1
- package/dist/modules/settings_merge.d.ts.map +1 -1
- package/dist/modules/settings_merge.js +3 -1
- package/dist/modules/settings_merge.js.map +1 -1
- package/dist/modules/storage/browser_adapter.d.ts +8 -3
- package/dist/modules/storage/browser_adapter.d.ts.map +1 -1
- package/dist/modules/storage/browser_adapter.js +53 -4
- package/dist/modules/storage/browser_adapter.js.map +1 -1
- package/dist/modules/utils/sanitize_key.d.ts +7 -0
- package/dist/modules/utils/sanitize_key.d.ts.map +1 -0
- package/dist/modules/utils/sanitize_key.js +15 -0
- package/dist/modules/utils/sanitize_key.js.map +1 -0
- package/dist/pm2.js +6 -6
- package/dist/pm2.js.map +1 -1
- package/dist/scripts/analyze-orders.d.ts +2 -2
- package/dist/scripts/analyze-orders.d.ts.map +1 -1
- package/dist/scripts/analyze-orders.js +4 -12
- package/dist/scripts/analyze-orders.js.map +1 -1
- package/dist/scripts/runner.js +1 -1
- package/dist/scripts/runner.js.map +1 -1
- package/dist/scripts/update.js +1 -1
- package/dist/scripts/update.js.map +1 -1
- package/docs/BITSHARES_ONBOARDING.md +63 -18
- package/docs/COPY_ON_WRITE_MASTER_PLAN.md +5 -14
- package/docs/COW_INVARIANTS.md +4 -4
- package/docs/CREDENTIAL_SECURITY.md +0 -11
- package/docs/DEXBOT_COMPARISON.md +11 -11
- package/docs/EVOLUTION.md +11 -10
- package/docs/FUND_MOVEMENT_AND_ACCOUNTING.md +27 -83
- package/docs/GRID_RECALCULATION.md +1 -13
- package/docs/GRID_RECONCILE.md +24 -24
- package/docs/LIFECYCLE.md +4 -4
- package/docs/LOGGING.md +1 -1
- package/docs/MPA_CREDIT_USAGE.md +3 -3
- package/docs/README.md +2 -2
- package/docs/WORKFLOW.md +2 -2
- package/docs/architecture.md +43 -38
- package/docs/developer_guide.md +16 -18
- package/market_adapter/README.md +0 -2
- package/modules/README.md +2 -1
- package/package.json +1 -1
- package/scripts/README.md +1 -1
- package/claw/openclaw.plugin.json +0 -13
- package/dist/market_adapter/merge_lp_data.d.ts +0 -3
- package/dist/market_adapter/merge_lp_data.d.ts.map +0 -1
- package/dist/market_adapter/merge_lp_data.js +0 -125
- package/dist/market_adapter/merge_lp_data.js.map +0 -1
- package/dist/market_adapter/utils/paths.d.ts +0 -3
- package/dist/market_adapter/utils/paths.d.ts.map +0 -1
- package/dist/market_adapter/utils/paths.js +0 -5
- package/dist/market_adapter/utils/paths.js.map +0 -1
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
import definePluginEntry from 'openclaw/plugin-sdk/plugin-entry';
|
|
4
4
|
import { getClawToolCatalog } from '../../modules/claw_catalog.js';
|
|
5
5
|
import { runClawCommand } from '../../modules/claw_bridge.js';
|
|
6
|
+
import { getErrorMessage } from '../../../modules/utils/errors.js';
|
|
7
|
+
|
|
6
8
|
function formatResult(result: any) {
|
|
7
9
|
return JSON.stringify(result, null, 2);
|
|
8
10
|
}
|
|
@@ -18,16 +20,31 @@ const plugin = definePluginEntry({
|
|
|
18
20
|
description: `[${tool.risk}] ${tool.description}`,
|
|
19
21
|
parameters: tool.inputSchema,
|
|
20
22
|
async execute(_id: any, params: any) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
// Match the MCP servers' convention: tool failures surface as an
|
|
24
|
+
// isError result instead of a raw rejected promise.
|
|
25
|
+
try {
|
|
26
|
+
const result = await runClawCommand(tool.command, { ...params, runtimeName: 'openclaw' });
|
|
27
|
+
return {
|
|
28
|
+
content: [
|
|
29
|
+
{
|
|
30
|
+
type: "text",
|
|
31
|
+
text: formatResult(result)
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
structuredContent: result
|
|
35
|
+
};
|
|
36
|
+
} catch (error: any) {
|
|
37
|
+
const text = error && error.stack ? error.stack : getErrorMessage(error);
|
|
38
|
+
return {
|
|
39
|
+
content: [
|
|
40
|
+
{
|
|
41
|
+
type: "text",
|
|
42
|
+
text
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
isError: true
|
|
46
|
+
};
|
|
47
|
+
}
|
|
31
48
|
}
|
|
32
49
|
});
|
|
33
50
|
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// console shim has been installed. Static imports here are limited to the
|
|
7
7
|
// lightweight transport helpers (mcp_utils) which never write to stdout.
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { createJsonRpcToolsHandler, jsonRpcError, runMcpServer, createMessageParser } from '../modules/mcp_utils.js';
|
|
10
10
|
import { pathToFileURL } from 'node:url';
|
|
11
11
|
|
|
12
12
|
console.log = () => {};
|
|
@@ -59,84 +59,26 @@ async function listMcpTools() {
|
|
|
59
59
|
}));
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
async function
|
|
63
|
-
const {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return success(id, {
|
|
68
|
-
// Echo the client's requested protocol version when provided, so a
|
|
69
|
-
// JSONL-speaking client can negotiate its own version.
|
|
70
|
-
protocolVersion: params?.protocolVersion || '2024-11-05',
|
|
71
|
-
capabilities: {
|
|
72
|
-
tools: {
|
|
73
|
-
listChanged: false
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
serverInfo: {
|
|
77
|
-
name: 'bitshares-claw',
|
|
78
|
-
version: '0.1.0'
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
case 'notifications/initialized':
|
|
83
|
-
return;
|
|
84
|
-
|
|
85
|
-
case 'ping':
|
|
86
|
-
return success(id, {});
|
|
87
|
-
|
|
88
|
-
case 'tools/list':
|
|
89
|
-
try {
|
|
90
|
-
return success(id, {
|
|
91
|
-
tools: await listMcpTools()
|
|
92
|
-
});
|
|
93
|
-
} catch (error: any) {
|
|
94
|
-
return failure(id, -32602, `Failed to load tool catalog: ${error && error.message ? error.message : String(error)}`);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
case 'tools/call': {
|
|
98
|
-
try {
|
|
99
|
-
const { getClawToolByName } = await import('../modules/claw_catalog.js');
|
|
100
|
-
const tool = getClawToolByName(params?.name);
|
|
101
|
-
if (!tool) {
|
|
102
|
-
return failure(id, -32602, `Unknown tool: ${params?.name || '(missing)'}`);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const { runClawCommand } = await import('../modules/claw_bridge.js');
|
|
106
|
-
const result = await runClawCommand(tool.command, {
|
|
107
|
-
...defaults,
|
|
108
|
-
...(params?.arguments || {})
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
return success(id, {
|
|
112
|
-
content: [
|
|
113
|
-
{
|
|
114
|
-
type: 'text',
|
|
115
|
-
text: JSON.stringify(result, null, 2)
|
|
116
|
-
}
|
|
117
|
-
],
|
|
118
|
-
structuredContent: result
|
|
119
|
-
});
|
|
120
|
-
} catch (error: any) {
|
|
121
|
-
return success(id, {
|
|
122
|
-
content: [
|
|
123
|
-
{
|
|
124
|
-
type: 'text',
|
|
125
|
-
text: error && error.stack ? error.stack : String(error)
|
|
126
|
-
}
|
|
127
|
-
],
|
|
128
|
-
isError: true
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
default:
|
|
134
|
-
if (id !== undefined) {
|
|
135
|
-
return failure(id, -32601, `Method not found: ${method}`);
|
|
136
|
-
}
|
|
62
|
+
async function callTool(params: any, defaults: any) {
|
|
63
|
+
const { getClawToolByName } = await import('../modules/claw_catalog.js');
|
|
64
|
+
const tool = getClawToolByName(params?.name);
|
|
65
|
+
if (!tool) {
|
|
66
|
+
throw jsonRpcError(-32602, `Unknown tool: ${params?.name || '(missing)'}`);
|
|
137
67
|
}
|
|
68
|
+
|
|
69
|
+
const { runClawCommand } = await import('../modules/claw_bridge.js');
|
|
70
|
+
return runClawCommand(tool.command, {
|
|
71
|
+
...defaults,
|
|
72
|
+
...(params?.arguments || {})
|
|
73
|
+
});
|
|
138
74
|
}
|
|
139
75
|
|
|
76
|
+
const handleRequest = createJsonRpcToolsHandler({
|
|
77
|
+
serverName: 'bitshares-claw',
|
|
78
|
+
listTools: listMcpTools,
|
|
79
|
+
callTool
|
|
80
|
+
});
|
|
81
|
+
|
|
140
82
|
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
141
83
|
runMcpServer(parseArgs, handleRequest).catch((err: unknown) => {
|
|
142
84
|
process.stderr.write(`${err instanceof Error && err.stack ? err.stack : String(err)}\n`);
|
|
@@ -144,5 +86,4 @@ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href)
|
|
|
144
86
|
});
|
|
145
87
|
}
|
|
146
88
|
|
|
147
|
-
export { createMessageParser,
|
|
148
|
-
|
|
89
|
+
export { createMessageParser, handleRequest }
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { getAsset, getBackingAsset, getBitassetData, getCallOrders, getDynamicGlobalProperties
|
|
2
|
-
import {
|
|
1
|
+
import { getAsset, getBackingAsset, getBitassetData, getCallOrders, getDynamicGlobalProperties } from '../modules/chain_queries.js';
|
|
2
|
+
import { getHonestMoneyBridge, isMpa, paginateListAssets } from '../modules/honest_ecosystem.js';
|
|
3
3
|
import { getErrorMessage } from '../../modules/utils/errors.js';
|
|
4
4
|
|
|
5
5
|
const DEFAULT_BATCH_SIZE = 100;
|
|
@@ -49,67 +49,17 @@ function toPositiveInteger(value: any, fallback: any) {
|
|
|
49
49
|
return Number.isInteger(value) && value > 0 ? value : fallback;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
function isMpa(asset: any) {
|
|
53
|
-
return Boolean(asset && asset.bitasset_data_id);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function isHonestAsset(asset: any) {
|
|
57
|
-
return typeof asset?.symbol === 'string' && asset.symbol.startsWith('HONEST.');
|
|
58
|
-
}
|
|
59
|
-
|
|
60
52
|
async function fetchAllAssets({ batchSize, maxPages, startSymbol }: { batchSize: any; maxPages: any; startSymbol: any }) {
|
|
61
|
-
const results = [];
|
|
62
|
-
|
|
63
|
-
let previousLastSymbol = null;
|
|
64
|
-
|
|
65
|
-
for (let page = 0; page < maxPages; page += 1) {
|
|
66
|
-
const batch = await listAssets(lowerBound, batchSize);
|
|
67
|
-
if (!Array.isArray(batch) || batch.length === 0) {
|
|
68
|
-
break;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
let pageItems = batch.filter(Boolean);
|
|
72
|
-
if (previousLastSymbol && pageItems[0]?.symbol === previousLastSymbol) {
|
|
73
|
-
pageItems = pageItems.slice(1);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (pageItems.length === 0) {
|
|
77
|
-
break;
|
|
78
|
-
}
|
|
79
|
-
|
|
53
|
+
const results: any[] = [];
|
|
54
|
+
await paginateListAssets({ batchSize, maxPages, startSymbol }, (pageItems) => {
|
|
80
55
|
results.push(...pageItems);
|
|
81
|
-
|
|
82
|
-
lowerBound = previousLastSymbol;
|
|
83
|
-
|
|
84
|
-
if (batch.length < batchSize) {
|
|
85
|
-
break;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
56
|
+
});
|
|
89
57
|
return results;
|
|
90
58
|
}
|
|
91
59
|
|
|
92
60
|
async function fetchAssetsByPrefix({ batchSize, maxPages, prefix, startSymbol }: { batchSize: any; maxPages: any; prefix: any; startSymbol: any }) {
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
let previousLastSymbol = null;
|
|
96
|
-
|
|
97
|
-
for (let page = 0; page < maxPages; page += 1) {
|
|
98
|
-
const batch = await listAssets(lowerBound, batchSize);
|
|
99
|
-
if (!Array.isArray(batch) || batch.length === 0) {
|
|
100
|
-
break;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
let pageItems = batch.filter(Boolean);
|
|
104
|
-
if (previousLastSymbol && pageItems[0]?.symbol === previousLastSymbol) {
|
|
105
|
-
pageItems = pageItems.slice(1);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (pageItems.length === 0) {
|
|
109
|
-
break;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const matching = [];
|
|
61
|
+
const matching: any[] = [];
|
|
62
|
+
await paginateListAssets({ batchSize, maxPages, startSymbol }, (pageItems) => {
|
|
113
63
|
let crossedPrefixBoundary = false;
|
|
114
64
|
|
|
115
65
|
for (const item of pageItems) {
|
|
@@ -125,18 +75,10 @@ async function fetchAssetsByPrefix({ batchSize, maxPages, prefix, startSymbol }:
|
|
|
125
75
|
}
|
|
126
76
|
}
|
|
127
77
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const lastItem = pageItems[pageItems.length - 1];
|
|
131
|
-
previousLastSymbol = lastItem?.symbol || previousLastSymbol;
|
|
132
|
-
lowerBound = previousLastSymbol || lowerBound;
|
|
133
|
-
|
|
134
|
-
if (crossedPrefixBoundary || batch.length < batchSize) {
|
|
135
|
-
break;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
78
|
+
return !crossedPrefixBoundary;
|
|
79
|
+
});
|
|
138
80
|
|
|
139
|
-
return
|
|
81
|
+
return matching;
|
|
140
82
|
}
|
|
141
83
|
|
|
142
84
|
async function mapWithConcurrency(items: any, concurrency: any, mapper: any) {
|
|
@@ -179,16 +121,14 @@ function computeBasePerQuote(priceObject: any, assetMap: any) {
|
|
|
179
121
|
}
|
|
180
122
|
|
|
181
123
|
async function getHonestMoneyPerBts(referenceAsset: any, coreAsset: any) {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
const latestHonestMoneyPerBts = referenceSide.amount / coreSide.amount;
|
|
191
|
-
if (!Number.isFinite(latestHonestMoneyPerBts) || latestHonestMoneyPerBts <= 0) {
|
|
124
|
+
// Prefer the live HONEST.MONEY/BTS pool (60s-cached); the module falls back
|
|
125
|
+
// to the hardcoded snapshot when the node cannot serve reserves. Reading the
|
|
126
|
+
// live bridge here keeps this report — whose purpose is refreshing those
|
|
127
|
+
// hardcoded values — from always printing stale fallback data.
|
|
128
|
+
const bridge = await getHonestMoneyBridge();
|
|
129
|
+
const latestHonestMoneyPerBts = bridge?.latestHonestMoneyPerBts ?? null;
|
|
130
|
+
|
|
131
|
+
if (latestHonestMoneyPerBts === null || !Number.isFinite(latestHonestMoneyPerBts) || latestHonestMoneyPerBts <= 0) {
|
|
192
132
|
return null;
|
|
193
133
|
}
|
|
194
134
|
|
|
@@ -197,8 +137,7 @@ async function getHonestMoneyPerBts(referenceAsset: any, coreAsset: any) {
|
|
|
197
137
|
id: bridge.liquidityPool.id,
|
|
198
138
|
poolSymbol: bridge.liquidityPool.poolSymbol,
|
|
199
139
|
reserves: [
|
|
200
|
-
bridge.liquidityPool.reserves
|
|
201
|
-
bridge.liquidityPool.reserves[1]
|
|
140
|
+
...bridge.liquidityPool.reserves
|
|
202
141
|
],
|
|
203
142
|
takerFeePercent: bridge.liquidityPool.takerFeePercent,
|
|
204
143
|
withdrawalFeePercent: bridge.liquidityPool.withdrawalFeePercent
|
|
@@ -235,15 +174,12 @@ async function getReferenceFeedData(asset: any, referenceAsset: any, coreAsset:
|
|
|
235
174
|
return null;
|
|
236
175
|
}
|
|
237
176
|
|
|
238
|
-
let assetPerBts = null;
|
|
239
177
|
let btsPerAsset = null;
|
|
240
178
|
|
|
241
179
|
if (settlementPrice.base.asset_id === asset.id && settlementPrice.quote.asset_id === coreAsset.id) {
|
|
242
|
-
assetPerBts = basePerQuote;
|
|
243
180
|
btsPerAsset = 1 / basePerQuote;
|
|
244
181
|
} else if (settlementPrice.base.asset_id === coreAsset.id && settlementPrice.quote.asset_id === asset.id) {
|
|
245
182
|
btsPerAsset = basePerQuote;
|
|
246
|
-
assetPerBts = 1 / basePerQuote;
|
|
247
183
|
} else {
|
|
248
184
|
return null;
|
|
249
185
|
}
|
|
@@ -345,7 +281,6 @@ async function main() {
|
|
|
345
281
|
const scopedAssets = options.allMpas
|
|
346
282
|
? allAssets.filter(isMpa).sort((a, b) => a.symbol.localeCompare(b.symbol))
|
|
347
283
|
: allAssets.filter((asset) => asset?.symbol?.startsWith(options.prefix)).sort((a, b) => a.symbol.localeCompare(b.symbol));
|
|
348
|
-
const mpas = scopedAssets.filter(isMpa);
|
|
349
284
|
const assetMap = new Map([coreAsset, referenceAsset, ...scopedAssets].filter(Boolean).map((asset) => [asset.id, asset]));
|
|
350
285
|
|
|
351
286
|
const scopedAssetRecords = await mapWithConcurrency(scopedAssets, 4, async (asset: any) => {
|
|
@@ -4,13 +4,43 @@
|
|
|
4
4
|
// the full claw catalog (via claw_manifest), so suppress incidental console
|
|
5
5
|
// logs the same way claw_mcp_server does.
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { runMemuCommand } from '../modules/memu_bridge.js';
|
|
7
|
+
import { createJsonRpcToolsHandler, jsonRpcError, runMcpServer } from '../modules/mcp_utils.js';
|
|
8
|
+
import { runMemuCommand, validateMemuCommandArgs } from '../modules/memu_bridge.js';
|
|
10
9
|
import { pathToFileURL } from 'node:url';
|
|
10
|
+
import { getErrorMessage } from '../../modules/utils/errors.js';
|
|
11
11
|
|
|
12
12
|
console.log = () => {};
|
|
13
13
|
console.warn = () => {};
|
|
14
|
+
|
|
15
|
+
// MCP tool name -> runMemuCommand command.
|
|
16
|
+
const TOOL_COMMANDS: Record<string, string> = {
|
|
17
|
+
'memu_manifest': 'manifest',
|
|
18
|
+
'memu_memorize': 'memorize',
|
|
19
|
+
'memu_retrieve': 'retrieve',
|
|
20
|
+
'memu_list_categories': 'list-categories',
|
|
21
|
+
'memu_list_items': 'list-items',
|
|
22
|
+
'memu_create_item': 'create-item',
|
|
23
|
+
'memu_update_item': 'update-item',
|
|
24
|
+
'memu_delete_item': 'delete-item',
|
|
25
|
+
'memu_clear': 'clear',
|
|
26
|
+
'memu_status': 'status',
|
|
27
|
+
'memu_memorize_conversation': 'memorize-conversation',
|
|
28
|
+
'memu_memorize_trading_context': 'memorize-trading-context',
|
|
29
|
+
'memu_retrieve_trading_context': 'retrieve-trading-context'
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Redact a CLI argument that may carry secrets (LLM API keys, database DSNs).
|
|
34
|
+
* Malformed JSON must be reported without echoing the full raw value into
|
|
35
|
+
* error messages or process logs.
|
|
36
|
+
*/
|
|
37
|
+
function redactSensitiveArg(value: any) {
|
|
38
|
+
const text = String(value);
|
|
39
|
+
const prefixLength = 12;
|
|
40
|
+
const prefix = text.slice(0, Math.min(prefixLength, text.length));
|
|
41
|
+
return `${prefix}<...${text.length} chars redacted>`;
|
|
42
|
+
}
|
|
43
|
+
|
|
14
44
|
function parseArgs(argv: any) {
|
|
15
45
|
const options: Record<string, any> = {};
|
|
16
46
|
|
|
@@ -33,8 +63,8 @@ function parseArgs(argv: any) {
|
|
|
33
63
|
if (arg === '--llm-profile' && next) {
|
|
34
64
|
try {
|
|
35
65
|
options.llmProfiles = JSON.parse(next);
|
|
36
|
-
} catch
|
|
37
|
-
throw new Error(`Invalid JSON for --llm-profile: ${next}`);
|
|
66
|
+
} catch {
|
|
67
|
+
throw new Error(`Invalid JSON for --llm-profile: ${redactSensitiveArg(next)}`);
|
|
38
68
|
}
|
|
39
69
|
i += 1;
|
|
40
70
|
continue;
|
|
@@ -43,8 +73,8 @@ function parseArgs(argv: any) {
|
|
|
43
73
|
if (arg === '--db-config' && next) {
|
|
44
74
|
try {
|
|
45
75
|
options.databaseConfig = JSON.parse(next);
|
|
46
|
-
} catch
|
|
47
|
-
throw new Error(`Invalid JSON for --db-config: ${next}`);
|
|
76
|
+
} catch {
|
|
77
|
+
throw new Error(`Invalid JSON for --db-config: ${redactSensitiveArg(next)}`);
|
|
48
78
|
}
|
|
49
79
|
i += 1;
|
|
50
80
|
continue;
|
|
@@ -54,7 +84,7 @@ function parseArgs(argv: any) {
|
|
|
54
84
|
return options;
|
|
55
85
|
}
|
|
56
86
|
|
|
57
|
-
function listMcpTools() {
|
|
87
|
+
async function listMcpTools() {
|
|
58
88
|
return [
|
|
59
89
|
{
|
|
60
90
|
name: 'memu_manifest',
|
|
@@ -286,158 +316,31 @@ function listMcpTools() {
|
|
|
286
316
|
];
|
|
287
317
|
}
|
|
288
318
|
|
|
289
|
-
async function
|
|
290
|
-
const
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
// Echo the client's requested protocol version when provided (JSONL
|
|
296
|
-
// transport; see claw_runtime_matrix.ts).
|
|
297
|
-
protocolVersion: params?.protocolVersion || '2024-11-05',
|
|
298
|
-
capabilities: {
|
|
299
|
-
tools: {
|
|
300
|
-
listChanged: false
|
|
301
|
-
}
|
|
302
|
-
},
|
|
303
|
-
serverInfo: {
|
|
304
|
-
name: 'bitshares-memu',
|
|
305
|
-
version: '0.1.0'
|
|
306
|
-
}
|
|
307
|
-
});
|
|
308
|
-
|
|
309
|
-
case 'notifications/initialized':
|
|
310
|
-
return;
|
|
311
|
-
|
|
312
|
-
case 'ping':
|
|
313
|
-
return success(id, {});
|
|
314
|
-
|
|
315
|
-
case 'tools/list':
|
|
316
|
-
return success(id, {
|
|
317
|
-
tools: listMcpTools()
|
|
318
|
-
});
|
|
319
|
-
|
|
320
|
-
case 'tools/call': {
|
|
321
|
-
const toolName = params?.name;
|
|
322
|
-
const args = params?.arguments || {};
|
|
323
|
-
|
|
324
|
-
try {
|
|
325
|
-
let result;
|
|
326
|
-
|
|
327
|
-
switch (toolName) {
|
|
328
|
-
case 'memu_manifest':
|
|
329
|
-
result = describeMemuBridge(defaults);
|
|
330
|
-
break;
|
|
331
|
-
|
|
332
|
-
case 'memu_memorize':
|
|
333
|
-
if (!args.resourceUrl || !args.modality) {
|
|
334
|
-
return failure(id, -32602, 'memu_memorize requires resourceUrl and modality');
|
|
335
|
-
}
|
|
336
|
-
result = await runMemuTool('memorize', args, defaults);
|
|
337
|
-
break;
|
|
338
|
-
|
|
339
|
-
case 'memu_retrieve':
|
|
340
|
-
if (!args.queries) {
|
|
341
|
-
return failure(id, -32602, 'memu_retrieve requires queries');
|
|
342
|
-
}
|
|
343
|
-
result = await runMemuTool('retrieve', args, defaults);
|
|
344
|
-
break;
|
|
345
|
-
|
|
346
|
-
case 'memu_list_categories':
|
|
347
|
-
result = await runMemuTool('list-categories', args, defaults);
|
|
348
|
-
break;
|
|
349
|
-
|
|
350
|
-
case 'memu_list_items':
|
|
351
|
-
result = await runMemuTool('list-items', args, defaults);
|
|
352
|
-
break;
|
|
353
|
-
|
|
354
|
-
case 'memu_create_item':
|
|
355
|
-
if (!(args.categoryId || args.categoryName) || !args.summary) {
|
|
356
|
-
return failure(id, -32602, 'memu_create_item requires categoryId or categoryName, plus summary');
|
|
357
|
-
}
|
|
358
|
-
result = await runMemuTool('create-item', args, defaults);
|
|
359
|
-
break;
|
|
360
|
-
|
|
361
|
-
case 'memu_update_item':
|
|
362
|
-
if (!args.itemId || !args.updates) {
|
|
363
|
-
return failure(id, -32602, 'memu_update_item requires itemId and updates');
|
|
364
|
-
}
|
|
365
|
-
result = await runMemuTool('update-item', args, defaults);
|
|
366
|
-
break;
|
|
367
|
-
|
|
368
|
-
case 'memu_delete_item':
|
|
369
|
-
if (!args.itemId) {
|
|
370
|
-
return failure(id, -32602, 'memu_delete_item requires itemId');
|
|
371
|
-
}
|
|
372
|
-
result = await runMemuTool('delete-item', args, defaults);
|
|
373
|
-
break;
|
|
374
|
-
|
|
375
|
-
case 'memu_clear':
|
|
376
|
-
result = await runMemuTool('clear', args, defaults);
|
|
377
|
-
break;
|
|
378
|
-
|
|
379
|
-
case 'memu_status':
|
|
380
|
-
result = await runMemuTool('status', args, defaults);
|
|
381
|
-
break;
|
|
382
|
-
|
|
383
|
-
case 'memu_memorize_conversation':
|
|
384
|
-
if (!args.messages) {
|
|
385
|
-
return failure(id, -32602, 'memu_memorize_conversation requires messages');
|
|
386
|
-
}
|
|
387
|
-
result = await runMemuTool('memorize-conversation', args, defaults);
|
|
388
|
-
break;
|
|
389
|
-
|
|
390
|
-
case 'memu_memorize_trading_context':
|
|
391
|
-
if (!args.context) {
|
|
392
|
-
return failure(id, -32602, 'memu_memorize_trading_context requires context');
|
|
393
|
-
}
|
|
394
|
-
result = await runMemuTool('memorize-trading-context', args, defaults);
|
|
395
|
-
break;
|
|
396
|
-
|
|
397
|
-
case 'memu_retrieve_trading_context':
|
|
398
|
-
if (!args.query) {
|
|
399
|
-
return failure(id, -32602, 'memu_retrieve_trading_context requires query');
|
|
400
|
-
}
|
|
401
|
-
result = await runMemuTool('retrieve-trading-context', args, defaults);
|
|
402
|
-
break;
|
|
403
|
-
|
|
404
|
-
default:
|
|
405
|
-
return failure(id, -32602, `Unknown tool: ${toolName}`);
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
return success(id, {
|
|
409
|
-
content: [
|
|
410
|
-
{
|
|
411
|
-
type: 'text',
|
|
412
|
-
text: JSON.stringify(result, null, 2)
|
|
413
|
-
}
|
|
414
|
-
],
|
|
415
|
-
structuredContent: result
|
|
416
|
-
});
|
|
417
|
-
} catch (error: any) {
|
|
418
|
-
return success(id, {
|
|
419
|
-
content: [
|
|
420
|
-
{
|
|
421
|
-
type: 'text',
|
|
422
|
-
text: error && error.stack ? error.stack : String(error)
|
|
423
|
-
}
|
|
424
|
-
],
|
|
425
|
-
isError: true
|
|
426
|
-
});
|
|
427
|
-
}
|
|
428
|
-
}
|
|
319
|
+
async function callTool(params: any, defaults: any) {
|
|
320
|
+
const toolName = params?.name;
|
|
321
|
+
const command = TOOL_COMMANDS[toolName];
|
|
322
|
+
if (!command) {
|
|
323
|
+
throw jsonRpcError(-32602, `Unknown tool: ${toolName}`);
|
|
324
|
+
}
|
|
429
325
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
326
|
+
const args = params?.arguments || {};
|
|
327
|
+
// Shared validation with runMemuCommand/claw_bridge so every surface rejects
|
|
328
|
+
// missing args with the same message; surfaced as invalid params (-32602).
|
|
329
|
+
try {
|
|
330
|
+
validateMemuCommandArgs(command, { ...defaults, ...args });
|
|
331
|
+
} catch (err: any) {
|
|
332
|
+
throw jsonRpcError(-32602, getErrorMessage(err));
|
|
434
333
|
}
|
|
435
|
-
}
|
|
436
334
|
|
|
437
|
-
async function runMemuTool(command: any, args: any, defaults: any) {
|
|
438
335
|
return runMemuCommand(command, { ...defaults, ...args });
|
|
439
336
|
}
|
|
440
337
|
|
|
338
|
+
const handleRequest = createJsonRpcToolsHandler({
|
|
339
|
+
serverName: 'bitshares-memu',
|
|
340
|
+
listTools: listMcpTools,
|
|
341
|
+
callTool
|
|
342
|
+
});
|
|
343
|
+
|
|
441
344
|
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
442
345
|
runMcpServer(parseArgs, handleRequest).catch((err: unknown) => {
|
|
443
346
|
process.stderr.write(`${err instanceof Error && err.stack ? err.stack : String(err)}\n`);
|
|
@@ -445,5 +348,4 @@ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href)
|
|
|
445
348
|
});
|
|
446
349
|
}
|
|
447
350
|
|
|
448
|
-
export { createMessageParser, failure, handleRequest, listMcpTools, success }
|
|
449
351
|
|
|
@@ -225,6 +225,9 @@ function createBridgeHarness() {
|
|
|
225
225
|
}
|
|
226
226
|
});
|
|
227
227
|
|
|
228
|
+
// Snapshot the real validator before the mock replaces the module: claw
|
|
229
|
+
// bridge delegates memu-* argument validation to it.
|
|
230
|
+
const realMemuBridge = require(memuBridgePath);
|
|
228
231
|
registerMock(memuBridgePath, {
|
|
229
232
|
describeMemuBridge: (options: any) => ({
|
|
230
233
|
options,
|
|
@@ -238,7 +241,8 @@ function createBridgeHarness() {
|
|
|
238
241
|
options,
|
|
239
242
|
source: 'memu'
|
|
240
243
|
};
|
|
241
|
-
}
|
|
244
|
+
},
|
|
245
|
+
validateMemuCommandArgs: realMemuBridge.validateMemuCommandArgs
|
|
242
246
|
});
|
|
243
247
|
|
|
244
248
|
clearModule(bridgePath);
|
|
@@ -499,7 +503,7 @@ async function testRunClawCommandDispatchMatrix() {
|
|
|
499
503
|
() => bridge.runClawCommand('memu-create-item', {
|
|
500
504
|
summary: 'missing category'
|
|
501
505
|
}),
|
|
502
|
-
/
|
|
506
|
+
/create-item requires categoryId or categoryName, plus summary/
|
|
503
507
|
);
|
|
504
508
|
|
|
505
509
|
await assert.rejects(
|
|
@@ -31,7 +31,7 @@ async function testParserAcceptsJsonlAcrossChunksAndSingleBuffer() {
|
|
|
31
31
|
capabilities: {},
|
|
32
32
|
clientInfo: {
|
|
33
33
|
name: 'claw-mcp-transport-test',
|
|
34
|
-
version: '1.4.
|
|
34
|
+
version: '1.4.21'
|
|
35
35
|
},
|
|
36
36
|
protocolVersion: '2024-11-05'
|
|
37
37
|
}
|
|
@@ -182,7 +182,7 @@ async function testMainEntrypointHandlesRealProcessInitialize() {
|
|
|
182
182
|
capabilities: {},
|
|
183
183
|
clientInfo: {
|
|
184
184
|
name: 'claw-mcp-transport-test',
|
|
185
|
-
version: '1.4.
|
|
185
|
+
version: '1.4.21'
|
|
186
186
|
},
|
|
187
187
|
protocolVersion: '2024-11-05'
|
|
188
188
|
}
|
|
@@ -85,7 +85,7 @@ function main() {
|
|
|
85
85
|
if (e.code === 'ENOENT') {
|
|
86
86
|
console.error(`Data file not found: ${opts.data}`);
|
|
87
87
|
console.error('Export LP candles first, or point --data at an existing file.');
|
|
88
|
-
console.error('
|
|
88
|
+
console.error(' node dist/market_adapter/inputs/fetch_lp_data.js --pool 133 --precA 4 --precB 5 --interval 1h --lookback 26280h');
|
|
89
89
|
}
|
|
90
90
|
else if (e instanceof SyntaxError) {
|
|
91
91
|
console.error(`Failed to parse JSON from: ${opts.data}`);
|