@decibelsystems/tools 2.2.0-beta.0 → 3.0.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.
Files changed (273) hide show
  1. package/CHANGELOG.md +160 -0
  2. package/dist/agentPresence.d.ts +80 -0
  3. package/dist/agentPresence.d.ts.map +1 -1
  4. package/dist/agentPresence.js +177 -0
  5. package/dist/agentPresence.js.map +1 -1
  6. package/dist/agentic/index.d.ts +18 -8
  7. package/dist/agentic/index.d.ts.map +1 -1
  8. package/dist/agentic/index.js +18 -144
  9. package/dist/agentic/index.js.map +1 -1
  10. package/dist/agentic/types.d.ts +106 -0
  11. package/dist/agentic/types.d.ts.map +1 -1
  12. package/dist/agentic/types.js +77 -1
  13. package/dist/agentic/types.js.map +1 -1
  14. package/dist/architectAdrs.d.ts +14 -2
  15. package/dist/architectAdrs.d.ts.map +1 -1
  16. package/dist/architectAdrs.js +9 -3
  17. package/dist/architectAdrs.js.map +1 -1
  18. package/dist/client/transports.d.ts.map +1 -1
  19. package/dist/client/transports.js +13 -3
  20. package/dist/client/transports.js.map +1 -1
  21. package/dist/daemon.d.ts +19 -0
  22. package/dist/daemon.d.ts.map +1 -1
  23. package/dist/daemon.js +181 -38
  24. package/dist/daemon.js.map +1 -1
  25. package/dist/daemonConfig.d.ts +24 -0
  26. package/dist/daemonConfig.d.ts.map +1 -1
  27. package/dist/daemonConfig.js +46 -12
  28. package/dist/daemonConfig.js.map +1 -1
  29. package/dist/decibelPaths.d.ts.map +1 -1
  30. package/dist/decibelPaths.js +39 -6
  31. package/dist/decibelPaths.js.map +1 -1
  32. package/dist/domain/issue.d.ts +77 -0
  33. package/dist/domain/issue.d.ts.map +1 -0
  34. package/dist/domain/issue.js +134 -0
  35. package/dist/domain/issue.js.map +1 -0
  36. package/dist/domain/issueCodec.d.ts +39 -0
  37. package/dist/domain/issueCodec.d.ts.map +1 -0
  38. package/dist/domain/issueCodec.js +298 -0
  39. package/dist/domain/issueCodec.js.map +1 -0
  40. package/dist/domain/issueRepository.d.ts +91 -0
  41. package/dist/domain/issueRepository.d.ts.map +1 -0
  42. package/dist/domain/issueRepository.js +257 -0
  43. package/dist/domain/issueRepository.js.map +1 -0
  44. package/dist/facades/definitions.d.ts +0 -1
  45. package/dist/facades/definitions.d.ts.map +1 -1
  46. package/dist/facades/definitions.js +94 -113
  47. package/dist/facades/definitions.js.map +1 -1
  48. package/dist/facades/index.d.ts +2 -1
  49. package/dist/facades/index.d.ts.map +1 -1
  50. package/dist/facades/index.js +1 -1
  51. package/dist/facades/index.js.map +1 -1
  52. package/dist/facades/types.d.ts +17 -0
  53. package/dist/facades/types.d.ts.map +1 -1
  54. package/dist/httpArgs.d.ts +11 -0
  55. package/dist/httpArgs.d.ts.map +1 -0
  56. package/dist/httpArgs.js +39 -0
  57. package/dist/httpArgs.js.map +1 -0
  58. package/dist/httpServer.d.ts +1 -12
  59. package/dist/httpServer.d.ts.map +1 -1
  60. package/dist/httpServer.js +97 -96
  61. package/dist/httpServer.js.map +1 -1
  62. package/dist/kernel.d.ts +46 -1
  63. package/dist/kernel.d.ts.map +1 -1
  64. package/dist/kernel.js +311 -26
  65. package/dist/kernel.js.map +1 -1
  66. package/dist/lib/agent-services/assumptions.d.ts.map +1 -1
  67. package/dist/lib/agent-services/assumptions.js +8 -2
  68. package/dist/lib/agent-services/assumptions.js.map +1 -1
  69. package/dist/lib/atomicWrite.d.ts +26 -0
  70. package/dist/lib/atomicWrite.d.ts.map +1 -0
  71. package/dist/lib/atomicWrite.js +73 -0
  72. package/dist/lib/atomicWrite.js.map +1 -0
  73. package/dist/lib/envelope.d.ts +31 -0
  74. package/dist/lib/envelope.d.ts.map +1 -0
  75. package/dist/lib/envelope.js +80 -0
  76. package/dist/lib/envelope.js.map +1 -0
  77. package/dist/lib/fileLock.d.ts +38 -0
  78. package/dist/lib/fileLock.d.ts.map +1 -0
  79. package/dist/lib/fileLock.js +124 -0
  80. package/dist/lib/fileLock.js.map +1 -0
  81. package/dist/lib/recordIdAllocator.d.ts +86 -0
  82. package/dist/lib/recordIdAllocator.d.ts.map +1 -0
  83. package/dist/lib/recordIdAllocator.js +161 -0
  84. package/dist/lib/recordIdAllocator.js.map +1 -0
  85. package/dist/projectRegistry.d.ts.map +1 -1
  86. package/dist/projectRegistry.js +11 -0
  87. package/dist/projectRegistry.js.map +1 -1
  88. package/dist/runtime/circuitBreaker.d.ts +95 -0
  89. package/dist/runtime/circuitBreaker.d.ts.map +1 -0
  90. package/dist/runtime/circuitBreaker.js +178 -0
  91. package/dist/runtime/circuitBreaker.js.map +1 -0
  92. package/dist/runtime/ensureRuntime.d.ts +103 -0
  93. package/dist/runtime/ensureRuntime.d.ts.map +1 -0
  94. package/dist/runtime/ensureRuntime.js +281 -0
  95. package/dist/runtime/ensureRuntime.js.map +1 -0
  96. package/dist/runtime/extensions.d.ts +57 -0
  97. package/dist/runtime/extensions.d.ts.map +1 -0
  98. package/dist/runtime/extensions.js +216 -0
  99. package/dist/runtime/extensions.js.map +1 -0
  100. package/dist/runtime/localHttp.d.ts +24 -0
  101. package/dist/runtime/localHttp.d.ts.map +1 -0
  102. package/dist/runtime/localHttp.js +84 -0
  103. package/dist/runtime/localHttp.js.map +1 -0
  104. package/dist/runtime/projectResolution.d.ts +29 -0
  105. package/dist/runtime/projectResolution.d.ts.map +1 -0
  106. package/dist/runtime/projectResolution.js +67 -0
  107. package/dist/runtime/projectResolution.js.map +1 -0
  108. package/dist/runtime/protocol.d.ts +62 -0
  109. package/dist/runtime/protocol.d.ts.map +1 -0
  110. package/dist/runtime/protocol.js +74 -0
  111. package/dist/runtime/protocol.js.map +1 -0
  112. package/dist/sentinelIssues.d.ts +26 -2
  113. package/dist/sentinelIssues.d.ts.map +1 -1
  114. package/dist/sentinelIssues.js +125 -64
  115. package/dist/sentinelIssues.js.map +1 -1
  116. package/dist/server.js +59 -12
  117. package/dist/server.js.map +1 -1
  118. package/dist/tools/agentic/index.d.ts.map +1 -1
  119. package/dist/tools/agentic/index.js +28 -2
  120. package/dist/tools/agentic/index.js.map +1 -1
  121. package/dist/tools/architect/index.d.ts.map +1 -1
  122. package/dist/tools/architect/index.js +7 -2
  123. package/dist/tools/architect/index.js.map +1 -1
  124. package/dist/tools/context.d.ts +10 -5
  125. package/dist/tools/context.d.ts.map +1 -1
  126. package/dist/tools/context.js +45 -18
  127. package/dist/tools/context.js.map +1 -1
  128. package/dist/tools/coordinator/coordinator.d.ts.map +1 -1
  129. package/dist/tools/coordinator/coordinator.js +48 -19
  130. package/dist/tools/coordinator/coordinator.js.map +1 -1
  131. package/dist/tools/crit.d.ts +2 -1
  132. package/dist/tools/crit.d.ts.map +1 -1
  133. package/dist/tools/crit.js +19 -4
  134. package/dist/tools/crit.js.map +1 -1
  135. package/dist/tools/designer/index.d.ts.map +1 -1
  136. package/dist/tools/designer/index.js +4 -3
  137. package/dist/tools/designer/index.js.map +1 -1
  138. package/dist/tools/designer/lateral-tools.d.ts.map +1 -1
  139. package/dist/tools/designer/lateral-tools.js +4 -2
  140. package/dist/tools/designer/lateral-tools.js.map +1 -1
  141. package/dist/tools/designer.d.ts +2 -1
  142. package/dist/tools/designer.d.ts.map +1 -1
  143. package/dist/tools/designer.js +24 -12
  144. package/dist/tools/designer.js.map +1 -1
  145. package/dist/tools/dojo.d.ts +3 -2
  146. package/dist/tools/dojo.d.ts.map +1 -1
  147. package/dist/tools/dojo.js +64 -22
  148. package/dist/tools/dojo.js.map +1 -1
  149. package/dist/tools/friction.d.ts.map +1 -1
  150. package/dist/tools/friction.js +16 -6
  151. package/dist/tools/friction.js.map +1 -1
  152. package/dist/tools/guardian.d.ts.map +1 -1
  153. package/dist/tools/guardian.js +6 -2
  154. package/dist/tools/guardian.js.map +1 -1
  155. package/dist/tools/hygiene/oracle-hygiene.d.ts.map +1 -1
  156. package/dist/tools/hygiene/oracle-hygiene.js +8 -2
  157. package/dist/tools/hygiene/oracle-hygiene.js.map +1 -1
  158. package/dist/tools/index.d.ts.map +1 -1
  159. package/dist/tools/index.js +27 -18
  160. package/dist/tools/index.js.map +1 -1
  161. package/dist/tools/learnings.d.ts +2 -1
  162. package/dist/tools/learnings.d.ts.map +1 -1
  163. package/dist/tools/learnings.js +31 -15
  164. package/dist/tools/learnings.js.map +1 -1
  165. package/dist/tools/oracle.d.ts.map +1 -1
  166. package/dist/tools/oracle.js +19 -6
  167. package/dist/tools/oracle.js.map +1 -1
  168. package/dist/tools/policy.d.ts +2 -1
  169. package/dist/tools/policy.d.ts.map +1 -1
  170. package/dist/tools/policy.js +28 -9
  171. package/dist/tools/policy.js.map +1 -1
  172. package/dist/tools/postoffice/index.d.ts +10 -0
  173. package/dist/tools/postoffice/index.d.ts.map +1 -0
  174. package/dist/tools/postoffice/index.js +218 -0
  175. package/dist/tools/postoffice/index.js.map +1 -0
  176. package/dist/tools/postoffice.d.ts +78 -0
  177. package/dist/tools/postoffice.d.ts.map +1 -0
  178. package/dist/tools/postoffice.js +199 -0
  179. package/dist/tools/postoffice.js.map +1 -0
  180. package/dist/tools/provenance.d.ts +7 -0
  181. package/dist/tools/provenance.d.ts.map +1 -1
  182. package/dist/tools/provenance.js +42 -16
  183. package/dist/tools/provenance.js.map +1 -1
  184. package/dist/tools/sentinel/index.d.ts +1 -0
  185. package/dist/tools/sentinel/index.d.ts.map +1 -1
  186. package/dist/tools/sentinel/index.js +88 -4
  187. package/dist/tools/sentinel/index.js.map +1 -1
  188. package/dist/tools/sentinel.d.ts +102 -1
  189. package/dist/tools/sentinel.d.ts.map +1 -1
  190. package/dist/tools/sentinel.js +544 -328
  191. package/dist/tools/sentinel.js.map +1 -1
  192. package/dist/tools/shared/index.d.ts +2 -1
  193. package/dist/tools/shared/index.d.ts.map +1 -1
  194. package/dist/tools/shared/index.js +2 -1
  195. package/dist/tools/shared/index.js.map +1 -1
  196. package/dist/tools/shared/response.d.ts +24 -0
  197. package/dist/tools/shared/response.d.ts.map +1 -1
  198. package/dist/tools/shared/response.js +61 -7
  199. package/dist/tools/shared/response.js.map +1 -1
  200. package/dist/tools/shared/storeRead.d.ts +153 -0
  201. package/dist/tools/shared/storeRead.d.ts.map +1 -0
  202. package/dist/tools/shared/storeRead.js +242 -0
  203. package/dist/tools/shared/storeRead.js.map +1 -0
  204. package/dist/tools/testSpec.d.ts +3 -2
  205. package/dist/tools/testSpec.d.ts.map +1 -1
  206. package/dist/tools/testSpec.js +51 -14
  207. package/dist/tools/testSpec.js.map +1 -1
  208. package/dist/tools/vector.d.ts +33 -1
  209. package/dist/tools/vector.d.ts.map +1 -1
  210. package/dist/tools/vector.js +31 -5
  211. package/dist/tools/vector.js.map +1 -1
  212. package/dist/tools/zoom/index.d.ts +15 -0
  213. package/dist/tools/zoom/index.d.ts.map +1 -0
  214. package/dist/tools/zoom/index.js +174 -0
  215. package/dist/tools/zoom/index.js.map +1 -0
  216. package/dist/tools/zoom.d.ts +234 -0
  217. package/dist/tools/zoom.d.ts.map +1 -0
  218. package/dist/tools/zoom.js +627 -0
  219. package/dist/tools/zoom.js.map +1 -0
  220. package/dist/transports/bridge.d.ts +1 -1
  221. package/dist/transports/bridge.d.ts.map +1 -1
  222. package/dist/transports/bridge.js +2 -0
  223. package/dist/transports/bridge.js.map +1 -1
  224. package/dist/transports/http.d.ts +1 -1
  225. package/dist/transports/http.d.ts.map +1 -1
  226. package/dist/transports/http.js +3 -1
  227. package/dist/transports/http.js.map +1 -1
  228. package/dist/transports/index.d.ts +1 -0
  229. package/dist/transports/index.d.ts.map +1 -1
  230. package/dist/transports/index.js +1 -0
  231. package/dist/transports/index.js.map +1 -1
  232. package/dist/transports/mcp.d.ts +1 -1
  233. package/dist/transports/mcp.d.ts.map +1 -1
  234. package/dist/transports/mcp.js +7 -3
  235. package/dist/transports/mcp.js.map +1 -1
  236. package/dist/transports/stdio.d.ts +1 -1
  237. package/dist/transports/stdio.d.ts.map +1 -1
  238. package/dist/transports/stdio.js +2 -0
  239. package/dist/transports/stdio.js.map +1 -1
  240. package/dist/transports/thinStdio.d.ts +22 -0
  241. package/dist/transports/thinStdio.d.ts.map +1 -0
  242. package/dist/transports/thinStdio.js +218 -0
  243. package/dist/transports/thinStdio.js.map +1 -0
  244. package/dist/transports/types.d.ts +8 -1
  245. package/dist/transports/types.d.ts.map +1 -1
  246. package/dist/types/agent-services.d.ts +7 -0
  247. package/dist/types/agent-services.d.ts.map +1 -1
  248. package/package.json +9 -4
  249. package/templates/com.decibel.daemon.plist +6 -1
  250. package/dist/tools/deck.d.ts +0 -11
  251. package/dist/tools/deck.d.ts.map +0 -1
  252. package/dist/tools/deck.js +0 -1656
  253. package/dist/tools/deck.js.map +0 -1
  254. package/dist/tools/mother.d.ts +0 -11
  255. package/dist/tools/mother.d.ts.map +0 -1
  256. package/dist/tools/mother.js +0 -503
  257. package/dist/tools/mother.js.map +0 -1
  258. package/dist/tools/registry.d.ts +0 -3
  259. package/dist/tools/registry.d.ts.map +0 -1
  260. package/dist/tools/registry.js +0 -189
  261. package/dist/tools/registry.js.map +0 -1
  262. package/dist/tools/senken.d.ts +0 -11
  263. package/dist/tools/senken.d.ts.map +0 -1
  264. package/dist/tools/senken.js +0 -482
  265. package/dist/tools/senken.js.map +0 -1
  266. package/dist/tools/terminal.d.ts +0 -17
  267. package/dist/tools/terminal.d.ts.map +0 -1
  268. package/dist/tools/terminal.js +0 -968
  269. package/dist/tools/terminal.js.map +0 -1
  270. package/dist/tools/toolsIndex.d.ts +0 -5
  271. package/dist/tools/toolsIndex.d.ts.map +0 -1
  272. package/dist/tools/toolsIndex.js +0 -37
  273. package/dist/tools/toolsIndex.js.map +0 -1
@@ -1,968 +0,0 @@
1
- /**
2
- * Terminal Markets Tools — DX Terminal Pro vault management
3
- *
4
- * REST API reads (market data, portfolios, strategies, competitors)
5
- * and on-chain writes (strategy updates, settings, deposits/withdrawals)
6
- * for the 21-day AI agent tournament on Base.
7
- *
8
- * Env vars:
9
- * DX_WALLET_ACCOUNT — cast keystore account name (preferred, e.g. "dx-tournament")
10
- * DX_WALLET_PASSWORD_FILE — path to keystore password file (required with DX_WALLET_ACCOUNT)
11
- * DX_WALLET_PRIVATE_KEY — raw private key fallback (less secure, use keystore instead)
12
- * DX_TERMINAL_VAULT — vault contract address (auto-resolved from wallet if missing)
13
- * DX_TERMINAL_RPC — Base RPC URL (default: https://mainnet.base.org)
14
- */
15
- import { execSync } from 'node:child_process';
16
- const API_BASE = 'https://api.terminal.markets/api/v1';
17
- const DEFAULT_RPC = 'https://mainnet.base.org';
18
- // ============================================================================
19
- // Helpers
20
- // ============================================================================
21
- function jsonResult(data, isError = false) {
22
- return {
23
- content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
24
- isError,
25
- };
26
- }
27
- function getRpc() {
28
- return process.env.DX_TERMINAL_RPC || DEFAULT_RPC;
29
- }
30
- /** Returns cast CLI flags for wallet authentication (keystore preferred, raw key fallback) */
31
- function getWalletFlags() {
32
- const account = process.env.DX_WALLET_ACCOUNT;
33
- if (account) {
34
- const passwordFile = process.env.DX_WALLET_PASSWORD_FILE;
35
- if (!passwordFile)
36
- throw new Error('DX_WALLET_PASSWORD_FILE required when using DX_WALLET_ACCOUNT');
37
- return `--account "${account}" --password-file "${passwordFile}"`;
38
- }
39
- const key = process.env.DX_WALLET_PRIVATE_KEY;
40
- if (key)
41
- return `--private-key "${key}"`;
42
- throw new Error('Wallet not configured. Set DX_WALLET_ACCOUNT + DX_WALLET_PASSWORD_FILE (recommended) or DX_WALLET_PRIVATE_KEY (fallback)');
43
- }
44
- /** Cached vault address — resolved once per process */
45
- let cachedVaultAddress = null;
46
- async function getVaultAddress() {
47
- if (cachedVaultAddress)
48
- return cachedVaultAddress;
49
- const explicit = process.env.DX_TERMINAL_VAULT;
50
- if (explicit) {
51
- cachedVaultAddress = explicit;
52
- return explicit;
53
- }
54
- // Derive owner address from wallet, then look up vault
55
- let ownerAddress;
56
- try {
57
- const account = process.env.DX_WALLET_ACCOUNT;
58
- if (account) {
59
- const passwordFile = process.env.DX_WALLET_PASSWORD_FILE;
60
- if (!passwordFile)
61
- throw new Error('DX_WALLET_PASSWORD_FILE required when using DX_WALLET_ACCOUNT');
62
- ownerAddress = execSync(`cast wallet address --account "${account}" --password-file "${passwordFile}"`, { encoding: 'utf8', timeout: 10000 }).trim();
63
- }
64
- else {
65
- const key = process.env.DX_WALLET_PRIVATE_KEY;
66
- if (!key)
67
- throw new Error('Wallet not configured. Set DX_WALLET_ACCOUNT or DX_WALLET_PRIVATE_KEY');
68
- ownerAddress = execSync(`cast wallet address --private-key "${key}"`, { encoding: 'utf8', timeout: 10000 }).trim();
69
- }
70
- }
71
- catch (err) {
72
- if (err.message?.includes('Wallet not configured') || err.message?.includes('PASSWORD_FILE'))
73
- throw err;
74
- const stderr = (err.stderr || '').toString().replace(/--private-key\s+"[^"]*"/, '--private-key "***"');
75
- throw new Error(`cast wallet address failed: ${stderr || 'unknown error'}`);
76
- }
77
- const res = await fetch(`${API_BASE}/vault?ownerAddress=${ownerAddress}`);
78
- if (!res.ok)
79
- throw new Error(`Vault lookup failed: ${res.status} ${res.statusText}`);
80
- const data = await res.json();
81
- const addr = data.vaultAddress;
82
- if (!addr)
83
- throw new Error(`No vault found for owner ${ownerAddress}`);
84
- cachedVaultAddress = addr;
85
- return addr;
86
- }
87
- /** Convert wei string to ETH (human-readable) */
88
- function weiToEth(wei) {
89
- const n = BigInt(wei);
90
- const whole = n / BigInt(1e18);
91
- const frac = n % BigInt(1e18);
92
- const fracStr = frac.toString().padStart(18, '0').slice(0, 6);
93
- return `${whole}.${fracStr}`;
94
- }
95
- async function apiFetch(path, params) {
96
- const url = new URL(`${API_BASE}${path}`);
97
- if (params) {
98
- for (const [k, v] of Object.entries(params)) {
99
- if (v !== undefined && v !== null && v !== '')
100
- url.searchParams.set(k, v);
101
- }
102
- }
103
- const res = await fetch(url.toString());
104
- if (!res.ok)
105
- throw new Error(`API ${path}: ${res.status} ${res.statusText}`);
106
- return res.json();
107
- }
108
- function castSend(contractAddress, sig, args, value) {
109
- const walletFlags = getWalletFlags();
110
- const rpc = getRpc();
111
- const valueFlag = value ? ` --value "${value}"` : '';
112
- const argsStr = args.map(a => `"${a}"`).join(' ');
113
- const cmd = `cast send "${contractAddress}" "${sig}" ${argsStr}${valueFlag} ${walletFlags} --rpc-url "${rpc}" --json`;
114
- try {
115
- const result = execSync(cmd, { encoding: 'utf8', timeout: 60000 });
116
- return JSON.parse(result);
117
- }
118
- catch (err) {
119
- // Never leak wallet flags (may contain --private-key) in error messages
120
- const stderr = (err.stderr || '').toString().replace(/--private-key\s+"[^"]*"/, '--private-key "***"');
121
- throw new Error(`cast send failed: ${stderr || 'unknown error'}`);
122
- }
123
- }
124
- // ============================================================================
125
- // READ TOOLS (REST API)
126
- // ============================================================================
127
- // Tool 1: terminal_get_tokens
128
- const terminalGetTokens = {
129
- definition: {
130
- name: 'terminal_get_tokens',
131
- description: 'Get all tokens in DX Terminal Pro with market data (market cap, price, volume). Use to identify leaders, laggards, and elimination candidates.',
132
- annotations: {
133
- title: 'Get Tokens',
134
- readOnlyHint: true,
135
- destructiveHint: false,
136
- openWorldHint: true,
137
- },
138
- inputSchema: {
139
- type: 'object',
140
- properties: {
141
- includeMarketData: {
142
- type: 'boolean',
143
- description: 'Include price, market cap, volume data (default: true)',
144
- },
145
- },
146
- required: [],
147
- },
148
- },
149
- handler: async (args) => {
150
- try {
151
- const data = await apiFetch('/tokens', {
152
- includeMarketData: String(args.includeMarketData ?? true),
153
- });
154
- // Sort by holder count descending as a proxy for popularity
155
- const sorted = data.sort((a, b) => {
156
- const hA = a.marketData?.holderCount || 0;
157
- const hB = b.marketData?.holderCount || 0;
158
- return hB - hA;
159
- });
160
- const summary = sorted.map((t, i) => ({
161
- rank: i + 1,
162
- symbol: t.symbol,
163
- name: t.name,
164
- address: t.tokenAddress,
165
- type: t.type,
166
- reaped: t.reaped,
167
- priceEth: t.marketData?.priceEth,
168
- priceUsd: t.marketData?.priceUsd,
169
- holderCount: t.marketData?.holderCount,
170
- volume24hEth: t.marketData?.['1d']?.volumeEth,
171
- volume24hUsd: t.marketData?.['1d']?.volumeUsd,
172
- priceChange24h: t.marketData?.['1d']?.priceChangePercent,
173
- buyCount24h: t.marketData?.['1d']?.buyCount,
174
- sellCount24h: t.marketData?.['1d']?.sellCount,
175
- }));
176
- return jsonResult({ success: true, tokenCount: summary.length, tokens: summary });
177
- }
178
- catch (error) {
179
- const msg = error instanceof Error ? error.message : String(error);
180
- return jsonResult({ success: false, error: msg }, true);
181
- }
182
- },
183
- };
184
- // Tool 2: terminal_get_portfolio
185
- const terminalGetPortfolio = {
186
- definition: {
187
- name: 'terminal_get_portfolio',
188
- description: 'Get your vault portfolio — ETH balance, token positions, overall PnL. Essential for understanding current exposure.',
189
- annotations: {
190
- title: 'Get Portfolio',
191
- readOnlyHint: true,
192
- destructiveHint: false,
193
- openWorldHint: true,
194
- },
195
- inputSchema: {
196
- type: 'object',
197
- properties: {
198
- vaultAddress: {
199
- type: 'string',
200
- description: 'Vault address (default: your vault)',
201
- },
202
- },
203
- required: [],
204
- },
205
- },
206
- handler: async (args) => {
207
- try {
208
- const vault = args.vaultAddress || await getVaultAddress();
209
- const data = await apiFetch(`/positions/${vault}`);
210
- return jsonResult({
211
- success: true,
212
- vault,
213
- ethBalance: weiToEth(data.ethBalance || '0'),
214
- overallValueEth: weiToEth(data.overallValueEth || '0'),
215
- overallValueUsd: data.overallValueUsd,
216
- overallPnlEth: weiToEth(data.overallPnlEth || '0'),
217
- overallPnlUsd: data.overallPnlUsd,
218
- overallPnlPercent: data.overallPnlPercent,
219
- positions: (data.positions || []).map((p) => ({
220
- ...p,
221
- balanceFormatted: p.balance ? weiToEth(p.balance) : undefined,
222
- })),
223
- });
224
- }
225
- catch (error) {
226
- const msg = error instanceof Error ? error.message : String(error);
227
- return jsonResult({ success: false, error: msg }, true);
228
- }
229
- },
230
- };
231
- // Tool 3: terminal_get_strategies
232
- const terminalGetStrategies = {
233
- definition: {
234
- name: 'terminal_get_strategies',
235
- description: 'Read active strategies for ANY vault (all strategies are public on-chain). Use to scout competitors or review your own.',
236
- annotations: {
237
- title: 'Get Strategies',
238
- readOnlyHint: true,
239
- destructiveHint: false,
240
- openWorldHint: true,
241
- },
242
- inputSchema: {
243
- type: 'object',
244
- properties: {
245
- vaultAddress: {
246
- type: 'string',
247
- description: 'Vault to read (default: your vault)',
248
- },
249
- activeOnly: {
250
- type: 'boolean',
251
- description: 'Only return active strategies (default: true)',
252
- },
253
- },
254
- required: [],
255
- },
256
- },
257
- handler: async (args) => {
258
- try {
259
- const vault = args.vaultAddress || await getVaultAddress();
260
- const data = await apiFetch(`/strategies/${vault}`, {
261
- activeOnly: String(args.activeOnly ?? true),
262
- });
263
- return jsonResult({
264
- success: true,
265
- vault,
266
- strategyCount: data.length,
267
- strategies: data.map((s) => ({
268
- id: s.strategyId,
269
- content: s.content,
270
- priority: s.strategyPriority,
271
- expiry: s.expiry,
272
- expiryDate: s.expiry ? new Date(Number(s.expiry) * 1000).toISOString() : null,
273
- enabled: s.enabled,
274
- })),
275
- });
276
- }
277
- catch (error) {
278
- const msg = error instanceof Error ? error.message : String(error);
279
- return jsonResult({ success: false, error: msg }, true);
280
- }
281
- },
282
- };
283
- // Tool 4: terminal_get_leaderboard
284
- const terminalGetLeaderboard = {
285
- definition: {
286
- name: 'terminal_get_leaderboard',
287
- description: 'Get vault rankings across all competitors. Use to identify top performers and read their strategies.',
288
- annotations: {
289
- title: 'Get Leaderboard',
290
- readOnlyHint: true,
291
- destructiveHint: false,
292
- openWorldHint: true,
293
- },
294
- inputSchema: {
295
- type: 'object',
296
- properties: {
297
- limit: {
298
- type: 'number',
299
- description: 'Number of vaults to return (default: 50)',
300
- },
301
- sortBy: {
302
- type: 'string',
303
- description: 'Sort field (default: total_pnl_usd)',
304
- },
305
- cursor: {
306
- type: 'string',
307
- description: 'Pagination cursor',
308
- },
309
- },
310
- required: [],
311
- },
312
- },
313
- handler: async (args) => {
314
- try {
315
- const data = await apiFetch('/leaderboard', {
316
- limit: String(args.limit ?? 50),
317
- sortBy: args.sortBy || 'total_pnl_usd',
318
- ...(args.cursor ? { cursor: args.cursor } : {}),
319
- });
320
- return jsonResult({ success: true, leaderboard: data });
321
- }
322
- catch (error) {
323
- const msg = error instanceof Error ? error.message : String(error);
324
- return jsonResult({ success: false, error: msg }, true);
325
- }
326
- },
327
- };
328
- // Tool 5: terminal_get_swaps
329
- const terminalGetSwaps = {
330
- definition: {
331
- name: 'terminal_get_swaps',
332
- description: 'Get trade history for a vault — includes amounts, tokens, and agent reasoning for each swap.',
333
- annotations: {
334
- title: 'Get Swaps',
335
- readOnlyHint: true,
336
- destructiveHint: false,
337
- openWorldHint: true,
338
- },
339
- inputSchema: {
340
- type: 'object',
341
- properties: {
342
- vaultAddress: {
343
- type: 'string',
344
- description: 'Vault address (default: your vault)',
345
- },
346
- limit: {
347
- type: 'number',
348
- description: 'Number of swaps (default: 50)',
349
- },
350
- order: {
351
- type: 'string',
352
- description: '"asc" or "desc" (default: desc)',
353
- },
354
- cursor: {
355
- type: 'string',
356
- description: 'Pagination cursor',
357
- },
358
- },
359
- required: [],
360
- },
361
- },
362
- handler: async (args) => {
363
- try {
364
- const vault = args.vaultAddress || await getVaultAddress();
365
- const data = await apiFetch('/swaps', {
366
- vaultAddress: vault,
367
- limit: String(args.limit ?? 50),
368
- order: args.order || 'desc',
369
- ...(args.cursor ? { cursor: args.cursor } : {}),
370
- });
371
- return jsonResult({ success: true, vault, swaps: data });
372
- }
373
- catch (error) {
374
- const msg = error instanceof Error ? error.message : String(error);
375
- return jsonResult({ success: false, error: msg }, true);
376
- }
377
- },
378
- };
379
- // Tool 6: terminal_get_inference_logs
380
- const terminalGetInferenceLogs = {
381
- definition: {
382
- name: 'terminal_get_inference_logs',
383
- description: 'Read Qwen3 decision reasoning for any vault. Shows how the AI interpreted strategies and decided on trades.',
384
- annotations: {
385
- title: 'Get Inference Logs',
386
- readOnlyHint: true,
387
- destructiveHint: false,
388
- openWorldHint: true,
389
- },
390
- inputSchema: {
391
- type: 'object',
392
- properties: {
393
- vaultAddress: {
394
- type: 'string',
395
- description: 'Vault address (default: your vault)',
396
- },
397
- limit: {
398
- type: 'number',
399
- description: 'Number of logs (default: 20)',
400
- },
401
- order: {
402
- type: 'string',
403
- description: '"asc" or "desc" (default: desc)',
404
- },
405
- cursor: {
406
- type: 'string',
407
- description: 'Pagination cursor',
408
- },
409
- },
410
- required: [],
411
- },
412
- },
413
- handler: async (args) => {
414
- try {
415
- const vault = args.vaultAddress || await getVaultAddress();
416
- const data = await apiFetch(`/logs/${vault}`, {
417
- limit: String(args.limit ?? 20),
418
- order: args.order || 'desc',
419
- ...(args.cursor ? { cursor: args.cursor } : {}),
420
- });
421
- return jsonResult({ success: true, vault, logs: data });
422
- }
423
- catch (error) {
424
- const msg = error instanceof Error ? error.message : String(error);
425
- return jsonResult({ success: false, error: msg }, true);
426
- }
427
- },
428
- };
429
- // Tool 7: terminal_get_holders
430
- const terminalGetHolders = {
431
- definition: {
432
- name: 'terminal_get_holders',
433
- description: 'Get holder distribution for a token. Use to detect whale concentration — tokens with broad distribution are safer bets.',
434
- annotations: {
435
- title: 'Get Token Holders',
436
- readOnlyHint: true,
437
- destructiveHint: false,
438
- openWorldHint: true,
439
- },
440
- inputSchema: {
441
- type: 'object',
442
- properties: {
443
- tokenAddress: {
444
- type: 'string',
445
- description: 'Token contract address (required)',
446
- },
447
- limit: {
448
- type: 'number',
449
- description: 'Number of holders (default: 50)',
450
- },
451
- offset: {
452
- type: 'number',
453
- description: 'Pagination offset (default: 0)',
454
- },
455
- order: {
456
- type: 'string',
457
- description: '"asc" or "desc" by balance (default: desc)',
458
- },
459
- },
460
- required: ['tokenAddress'],
461
- },
462
- },
463
- handler: async (args) => {
464
- try {
465
- const data = await apiFetch(`/holders/${args.tokenAddress}`, {
466
- limit: String(args.limit ?? 50),
467
- offset: String(args.offset ?? 0),
468
- order: args.order || 'desc',
469
- });
470
- const holders = data.map((h) => ({
471
- ...h,
472
- balanceFormatted: h.balance ? weiToEth(h.balance) : undefined,
473
- }));
474
- return jsonResult({ success: true, token: args.tokenAddress, holderCount: holders.length, holders });
475
- }
476
- catch (error) {
477
- const msg = error instanceof Error ? error.message : String(error);
478
- return jsonResult({ success: false, error: msg }, true);
479
- }
480
- },
481
- };
482
- // Tool 8: terminal_get_candles
483
- const terminalGetCandles = {
484
- definition: {
485
- name: 'terminal_get_candles',
486
- description: 'Get OHLCV candlestick data for a token. Use for momentum analysis and trend detection.',
487
- annotations: {
488
- title: 'Get Candles',
489
- readOnlyHint: true,
490
- destructiveHint: false,
491
- openWorldHint: true,
492
- },
493
- inputSchema: {
494
- type: 'object',
495
- properties: {
496
- tokenAddress: {
497
- type: 'string',
498
- description: 'Token contract address (required)',
499
- },
500
- timeframe: {
501
- type: 'string',
502
- description: 'Candle timeframe: 1m, 5m, 15m, 1h, 4h, 1d (default: 1h)',
503
- },
504
- countback: {
505
- type: 'number',
506
- description: 'Number of candles to return (default: 50)',
507
- },
508
- to: {
509
- type: 'number',
510
- description: 'End timestamp (unix seconds, default: now)',
511
- },
512
- },
513
- required: ['tokenAddress'],
514
- },
515
- },
516
- handler: async (args) => {
517
- try {
518
- const data = await apiFetch(`/candles/${args.tokenAddress}`, {
519
- timeframe: args.timeframe || '1h',
520
- countback: String(args.countback ?? 50),
521
- to: String(args.to ?? Math.floor(Date.now() / 1000)),
522
- });
523
- return jsonResult({ success: true, token: args.tokenAddress, candles: data });
524
- }
525
- catch (error) {
526
- const msg = error instanceof Error ? error.message : String(error);
527
- return jsonResult({ success: false, error: msg }, true);
528
- }
529
- },
530
- };
531
- // Tool 9: terminal_get_pnl_history
532
- const terminalGetPnlHistory = {
533
- definition: {
534
- name: 'terminal_get_pnl_history',
535
- description: 'Get PnL time series for a vault. Use to evaluate strategy performance over time.',
536
- annotations: {
537
- title: 'Get PnL History',
538
- readOnlyHint: true,
539
- destructiveHint: false,
540
- openWorldHint: true,
541
- },
542
- inputSchema: {
543
- type: 'object',
544
- properties: {
545
- vaultAddress: {
546
- type: 'string',
547
- description: 'Vault address (default: your vault)',
548
- },
549
- },
550
- required: [],
551
- },
552
- },
553
- handler: async (args) => {
554
- try {
555
- const vault = args.vaultAddress || await getVaultAddress();
556
- const data = await apiFetch(`/pnl-history/${vault}`);
557
- return jsonResult({ success: true, vault, pnlHistory: data });
558
- }
559
- catch (error) {
560
- const msg = error instanceof Error ? error.message : String(error);
561
- return jsonResult({ success: false, error: msg }, true);
562
- }
563
- },
564
- };
565
- // Tool 10: terminal_get_vault_settings
566
- const terminalGetVaultSettings = {
567
- definition: {
568
- name: 'terminal_get_vault_settings',
569
- description: 'Get vault configuration — behavioral sliders, max trade size, slippage settings.',
570
- annotations: {
571
- title: 'Get Vault Settings',
572
- readOnlyHint: true,
573
- destructiveHint: false,
574
- openWorldHint: true,
575
- },
576
- inputSchema: {
577
- type: 'object',
578
- properties: {
579
- vaultAddress: {
580
- type: 'string',
581
- description: 'Vault address (default: your vault)',
582
- },
583
- },
584
- required: [],
585
- },
586
- },
587
- handler: async (args) => {
588
- try {
589
- const vault = args.vaultAddress || await getVaultAddress();
590
- const data = await apiFetch('/vault', { vaultAddress: vault });
591
- return jsonResult({
592
- success: true,
593
- vault,
594
- settings: {
595
- maxTradeAmount: data.maxTradeAmount,
596
- slippageBps: data.slippageBps,
597
- tradingActivity: data.tradingActivity,
598
- assetRiskPreference: data.assetRiskPreference,
599
- tradeSize: data.tradeSize,
600
- holdingStyle: data.holdingStyle,
601
- diversification: data.diversification,
602
- },
603
- });
604
- }
605
- catch (error) {
606
- const msg = error instanceof Error ? error.message : String(error);
607
- return jsonResult({ success: false, error: msg }, true);
608
- }
609
- },
610
- };
611
- // Tool 11: terminal_get_deposits_withdrawals
612
- const terminalGetDepositsWithdrawals = {
613
- definition: {
614
- name: 'terminal_get_deposits_withdrawals',
615
- description: 'Get deposit and withdrawal history for a vault.',
616
- annotations: {
617
- title: 'Get Deposits/Withdrawals',
618
- readOnlyHint: true,
619
- destructiveHint: false,
620
- openWorldHint: true,
621
- },
622
- inputSchema: {
623
- type: 'object',
624
- properties: {
625
- vaultAddress: {
626
- type: 'string',
627
- description: 'Vault address (default: your vault)',
628
- },
629
- limit: {
630
- type: 'number',
631
- description: 'Number of records (default: 50)',
632
- },
633
- order: {
634
- type: 'string',
635
- description: '"asc" or "desc" (default: desc)',
636
- },
637
- },
638
- required: [],
639
- },
640
- },
641
- handler: async (args) => {
642
- try {
643
- const vault = args.vaultAddress || await getVaultAddress();
644
- const data = await apiFetch(`/deposits-withdrawals/${vault}`, {
645
- limit: String(args.limit ?? 50),
646
- order: args.order || 'desc',
647
- });
648
- return jsonResult({ success: true, vault, transactions: data });
649
- }
650
- catch (error) {
651
- const msg = error instanceof Error ? error.message : String(error);
652
- return jsonResult({ success: false, error: msg }, true);
653
- }
654
- },
655
- };
656
- // ============================================================================
657
- // WRITE TOOLS (On-chain via cast)
658
- // ============================================================================
659
- // Tool 12: terminal_add_strategy
660
- const terminalAddStrategy = {
661
- definition: {
662
- name: 'terminal_add_strategy',
663
- description: 'Push a natural language strategy on-chain for Qwen3 to interpret. Max 8 active, 1024 chars each. Strategies must be specific and actionable.',
664
- annotations: {
665
- title: 'Add Strategy',
666
- readOnlyHint: false,
667
- destructiveHint: false,
668
- openWorldHint: true,
669
- },
670
- inputSchema: {
671
- type: 'object',
672
- properties: {
673
- strategy: {
674
- type: 'string',
675
- description: 'Natural language strategy text (max 1024 chars)',
676
- },
677
- priority: {
678
- type: 'number',
679
- description: '0=Low, 1=Med, 2=High (default: 2)',
680
- },
681
- expiryMinutes: {
682
- type: 'number',
683
- description: 'Minutes until expiry (default: 35 for auto-refresh cycles)',
684
- },
685
- expiryTimestamp: {
686
- type: 'number',
687
- description: 'Explicit unix timestamp for expiry (overrides expiryMinutes)',
688
- },
689
- },
690
- required: ['strategy'],
691
- },
692
- },
693
- handler: async (args) => {
694
- try {
695
- // Validate
696
- if (args.strategy.length > 1024) {
697
- return jsonResult({ success: false, error: `Strategy too long: ${args.strategy.length}/1024 chars` }, true);
698
- }
699
- if (args.strategy.length === 0) {
700
- return jsonResult({ success: false, error: 'Strategy text cannot be empty' }, true);
701
- }
702
- const vault = await getVaultAddress();
703
- const priority = args.priority ?? 2;
704
- const expiry = args.expiryTimestamp ?? Math.floor(Date.now() / 1000) + (args.expiryMinutes ?? 35) * 60;
705
- if (priority < 0 || priority > 2) {
706
- return jsonResult({ success: false, error: 'Priority must be 0 (Low), 1 (Med), or 2 (High)' }, true);
707
- }
708
- const result = castSend(vault, 'addStrategy(string,uint64,uint8)', [
709
- args.strategy,
710
- String(expiry),
711
- String(priority),
712
- ]);
713
- return jsonResult({
714
- success: true,
715
- vault,
716
- strategy: args.strategy,
717
- priority: ['Low', 'Med', 'High'][priority],
718
- expiry,
719
- expiryDate: new Date(expiry * 1000).toISOString(),
720
- txHash: result?.transactionHash,
721
- });
722
- }
723
- catch (error) {
724
- const msg = error instanceof Error ? error.message : String(error);
725
- return jsonResult({ success: false, error: msg }, true);
726
- }
727
- },
728
- };
729
- // Tool 13: terminal_disable_strategy
730
- const terminalDisableStrategy = {
731
- definition: {
732
- name: 'terminal_disable_strategy',
733
- description: 'Disable a strategy by ID. Use to remove stale or expired strategies before adding new ones.',
734
- annotations: {
735
- title: 'Disable Strategy',
736
- readOnlyHint: false,
737
- destructiveHint: true,
738
- openWorldHint: true,
739
- },
740
- inputSchema: {
741
- type: 'object',
742
- properties: {
743
- strategyId: {
744
- type: 'string',
745
- description: 'Strategy ID to disable (from get_strategies)',
746
- },
747
- },
748
- required: ['strategyId'],
749
- },
750
- },
751
- handler: async (args) => {
752
- try {
753
- const vault = await getVaultAddress();
754
- const result = castSend(vault, 'disableStrategy(uint256)', [args.strategyId]);
755
- return jsonResult({
756
- success: true,
757
- vault,
758
- disabledStrategyId: args.strategyId,
759
- txHash: result?.transactionHash,
760
- });
761
- }
762
- catch (error) {
763
- const msg = error instanceof Error ? error.message : String(error);
764
- return jsonResult({ success: false, error: msg }, true);
765
- }
766
- },
767
- };
768
- // Tool 14: terminal_update_settings
769
- const terminalUpdateSettings = {
770
- definition: {
771
- name: 'terminal_update_settings',
772
- description: 'Update vault behavioral sliders and trade limits. All 7 parameters must be provided.',
773
- annotations: {
774
- title: 'Update Settings',
775
- readOnlyHint: false,
776
- destructiveHint: false,
777
- openWorldHint: true,
778
- },
779
- inputSchema: {
780
- type: 'object',
781
- properties: {
782
- maxTradeAmount: {
783
- type: 'number',
784
- description: 'Max trade size in BPS (500-10000, e.g. 5000 = 50%)',
785
- },
786
- slippageBps: {
787
- type: 'number',
788
- description: 'Max slippage in BPS (10-5000, e.g. 250 = 2.5%)',
789
- },
790
- tradingActivity: {
791
- type: 'number',
792
- description: '1=rare to 5=frequent',
793
- },
794
- assetRiskPreference: {
795
- type: 'number',
796
- description: '1=safer to 5=riskier',
797
- },
798
- tradeSize: {
799
- type: 'number',
800
- description: '1=cautious to 5=aggressive',
801
- },
802
- holdingStyle: {
803
- type: 'number',
804
- description: '1=short-term to 5=patient',
805
- },
806
- diversification: {
807
- type: 'number',
808
- description: '1=concentrated to 5=spread',
809
- },
810
- },
811
- required: [
812
- 'maxTradeAmount', 'slippageBps', 'tradingActivity',
813
- 'assetRiskPreference', 'tradeSize', 'holdingStyle', 'diversification',
814
- ],
815
- },
816
- },
817
- handler: async (args) => {
818
- try {
819
- // Validate ranges
820
- const sliders = ['tradingActivity', 'assetRiskPreference', 'tradeSize', 'holdingStyle', 'diversification'];
821
- for (const s of sliders) {
822
- if (args[s] < 1 || args[s] > 5) {
823
- return jsonResult({ success: false, error: `${s} must be 1-5, got ${args[s]}` }, true);
824
- }
825
- }
826
- if (args.maxTradeAmount < 500 || args.maxTradeAmount > 10000) {
827
- return jsonResult({ success: false, error: `maxTradeAmount must be 500-10000 BPS, got ${args.maxTradeAmount}` }, true);
828
- }
829
- if (args.slippageBps < 10 || args.slippageBps > 5000) {
830
- return jsonResult({ success: false, error: `slippageBps must be 10-5000, got ${args.slippageBps}` }, true);
831
- }
832
- const vault = await getVaultAddress();
833
- const tuple = `(${args.maxTradeAmount},${args.slippageBps},${args.tradingActivity},${args.assetRiskPreference},${args.tradeSize},${args.holdingStyle},${args.diversification})`;
834
- const result = castSend(vault, 'updateSettings((uint256,uint256,uint8,uint8,uint8,uint8,uint8))', [tuple]);
835
- return jsonResult({
836
- success: true,
837
- vault,
838
- settings: {
839
- maxTradeAmount: args.maxTradeAmount,
840
- slippageBps: args.slippageBps,
841
- tradingActivity: args.tradingActivity,
842
- assetRiskPreference: args.assetRiskPreference,
843
- tradeSize: args.tradeSize,
844
- holdingStyle: args.holdingStyle,
845
- diversification: args.diversification,
846
- },
847
- txHash: result?.transactionHash,
848
- });
849
- }
850
- catch (error) {
851
- const msg = error instanceof Error ? error.message : String(error);
852
- return jsonResult({ success: false, error: msg }, true);
853
- }
854
- },
855
- };
856
- // Tool 15: terminal_deposit_eth
857
- const terminalDepositEth = {
858
- definition: {
859
- name: 'terminal_deposit_eth',
860
- description: 'Deposit ETH into the vault. Amount in ether (e.g. 0.05).',
861
- annotations: {
862
- title: 'Deposit ETH',
863
- readOnlyHint: false,
864
- destructiveHint: false,
865
- openWorldHint: true,
866
- },
867
- inputSchema: {
868
- type: 'object',
869
- properties: {
870
- amount: {
871
- type: 'string',
872
- description: 'ETH amount to deposit (e.g. "0.05")',
873
- },
874
- },
875
- required: ['amount'],
876
- },
877
- },
878
- handler: async (args) => {
879
- try {
880
- const amountNum = parseFloat(args.amount);
881
- if (isNaN(amountNum) || amountNum <= 0) {
882
- return jsonResult({ success: false, error: 'Amount must be a positive number' }, true);
883
- }
884
- const vault = await getVaultAddress();
885
- const result = castSend(vault, 'depositETH()', [], `${args.amount}ether`);
886
- return jsonResult({
887
- success: true,
888
- vault,
889
- depositedEth: args.amount,
890
- txHash: result?.transactionHash,
891
- });
892
- }
893
- catch (error) {
894
- const msg = error instanceof Error ? error.message : String(error);
895
- return jsonResult({ success: false, error: msg }, true);
896
- }
897
- },
898
- };
899
- // Tool 16: terminal_withdraw_eth
900
- const terminalWithdrawEth = {
901
- definition: {
902
- name: 'terminal_withdraw_eth',
903
- description: 'Withdraw unallocated ETH from the vault. Amount in ether (e.g. 0.05). Only unallocated ETH can be withdrawn.',
904
- annotations: {
905
- title: 'Withdraw ETH',
906
- readOnlyHint: false,
907
- destructiveHint: true,
908
- openWorldHint: true,
909
- },
910
- inputSchema: {
911
- type: 'object',
912
- properties: {
913
- amount: {
914
- type: 'string',
915
- description: 'ETH amount to withdraw (e.g. "0.05")',
916
- },
917
- },
918
- required: ['amount'],
919
- },
920
- },
921
- handler: async (args) => {
922
- try {
923
- const amountNum = parseFloat(args.amount);
924
- if (isNaN(amountNum) || amountNum <= 0) {
925
- return jsonResult({ success: false, error: 'Amount must be a positive number' }, true);
926
- }
927
- // Convert ether to wei
928
- const wei = BigInt(Math.floor(amountNum * 1e18)).toString();
929
- const vault = await getVaultAddress();
930
- const result = castSend(vault, 'withdrawETH(uint256)', [wei]);
931
- return jsonResult({
932
- success: true,
933
- vault,
934
- withdrawnEth: args.amount,
935
- withdrawnWei: wei,
936
- txHash: result?.transactionHash,
937
- });
938
- }
939
- catch (error) {
940
- const msg = error instanceof Error ? error.message : String(error);
941
- return jsonResult({ success: false, error: msg }, true);
942
- }
943
- },
944
- };
945
- // ============================================================================
946
- // Export
947
- // ============================================================================
948
- export const terminalTools = [
949
- // Reads
950
- terminalGetTokens,
951
- terminalGetPortfolio,
952
- terminalGetStrategies,
953
- terminalGetLeaderboard,
954
- terminalGetSwaps,
955
- terminalGetInferenceLogs,
956
- terminalGetHolders,
957
- terminalGetCandles,
958
- terminalGetPnlHistory,
959
- terminalGetVaultSettings,
960
- terminalGetDepositsWithdrawals,
961
- // Writes
962
- terminalAddStrategy,
963
- terminalDisableStrategy,
964
- terminalUpdateSettings,
965
- terminalDepositEth,
966
- terminalWithdrawEth,
967
- ];
968
- //# sourceMappingURL=terminal.js.map