@moly-mcp/lido 1.1.4 → 1.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.js CHANGED
@@ -21,7 +21,6 @@ import {
21
21
  isCancel,
22
22
  spinner
23
23
  } from "@clack/prompts";
24
- import { generatePrivateKey } from "viem/accounts";
25
24
  function bail(value) {
26
25
  cancel("Setup cancelled.");
27
26
  process.exit(0);
@@ -192,44 +191,84 @@ async function runWizard() {
192
191
  }
193
192
  }
194
193
  if (owsSdk && wallets.length > 0) {
195
- const walletName = check(
194
+ const evmAddr = (w) => w.accounts?.find((a) => a.chainId === "evm")?.address ?? "";
195
+ const walletAction = check(
196
196
  await select({
197
- message: "Which OWS wallet?",
198
- options: wallets.map((w) => ({
199
- value: w.name,
200
- label: `${w.name} (${w.address.slice(0, 8)}...)`
201
- }))
197
+ message: "OWS wallet?",
198
+ options: [
199
+ ...wallets.map((w) => ({
200
+ value: w.name,
201
+ label: `${w.name} (${evmAddr(w).slice(0, 10)}...)`
202
+ })),
203
+ { value: "__import__", label: "Import existing private key into new wallet" },
204
+ { value: "__create__", label: "Create new wallet" }
205
+ ]
202
206
  })
203
207
  );
204
- const passphrase = check(
205
- await password({
206
- message: "OWS passphrase:",
207
- mask: "*"
208
+ if (walletAction === "__import__" || walletAction === "__create__") {
209
+ const wName = check(
210
+ await text({ message: "Wallet name:", placeholder: "moly", initialValue: "moly" })
211
+ );
212
+ const pp = check(
213
+ await password({ message: "Passphrase (encrypts the vault):", mask: "*" })
214
+ );
215
+ try {
216
+ if (walletAction === "__import__") {
217
+ const pk = check(
218
+ await password({ message: "Private key (0x...):", mask: "*" })
219
+ );
220
+ owsSdk.importWalletPrivateKey(wName.trim() || "moly", pk.trim(), pp.trim() || void 0);
221
+ } else {
222
+ owsSdk.createWallet(wName.trim() || "moly", pp.trim() || void 0);
223
+ }
224
+ ows = { walletName: wName.trim() || "moly", passphrase: pp.trim() };
225
+ } catch (err) {
226
+ note("OWS operation failed: " + err.message + "\nFalling back to raw key.", "Fallback");
227
+ const pk = check(
228
+ await password({ message: "Private key (0x...):", mask: "*" })
229
+ );
230
+ const t = pk.trim();
231
+ privateKey = t ? t.startsWith("0x") ? t : "0x" + t : null;
232
+ }
233
+ } else {
234
+ const passphrase = check(
235
+ await password({ message: "OWS passphrase:", mask: "*" })
236
+ );
237
+ ows = { walletName: walletAction, passphrase: passphrase.trim() };
238
+ }
239
+ } else if (owsSdk && wallets.length === 0) {
240
+ const walletAction = check(
241
+ await select({
242
+ message: "No wallets found. What would you like to do?",
243
+ options: [
244
+ { value: "import", label: "Import existing private key" },
245
+ { value: "create", label: "Generate new wallet" }
246
+ ]
208
247
  })
209
248
  );
210
- ows = { walletName, passphrase: passphrase.trim() };
211
- } else if (owsSdk && wallets.length === 0) {
212
- note("No OWS wallets found. Creating one for you...", "New OWS wallet");
213
249
  const walletName = check(
214
250
  await text({ message: "Wallet name:", placeholder: "moly", initialValue: "moly" })
215
251
  );
216
252
  const passphrase = check(
217
- await password({ message: "Set a passphrase (used to encrypt the key):", mask: "*" })
253
+ await password({ message: "Passphrase (encrypts the vault):", mask: "*" })
218
254
  );
219
- const s = spinner();
220
- s.start("Generating wallet...");
221
255
  try {
222
- const privateKey2 = generatePrivateKey();
223
- owsSdk.createWallet(walletName.trim() || "moly", passphrase.trim(), privateKey2);
224
- s.stop("Wallet created.");
256
+ if (walletAction === "import") {
257
+ const pk = check(
258
+ await password({ message: "Private key (0x...):", mask: "*" })
259
+ );
260
+ owsSdk.importWalletPrivateKey(walletName.trim() || "moly", pk.trim(), passphrase.trim() || void 0);
261
+ } else {
262
+ owsSdk.createWallet(walletName.trim() || "moly", passphrase.trim() || void 0);
263
+ }
225
264
  ows = { walletName: walletName.trim() || "moly", passphrase: passphrase.trim() };
226
265
  } catch (err) {
227
- s.stop("Auto-create failed: " + err.message);
228
- note("Falling back to raw private key storage.", "Fallback");
266
+ note("OWS operation failed: " + err.message + "\nFalling back to raw key.", "Fallback");
229
267
  const pk = check(
230
- await password({ message: "Enter or paste a private key (0x...) \u2014 or generate one:", mask: "*" })
268
+ await password({ message: "Private key (0x...):", mask: "*" })
231
269
  );
232
- privateKey = pk.trim() || null;
270
+ const t = pk.trim();
271
+ privateKey = t ? t.startsWith("0x") ? t : "0x" + t : null;
233
272
  }
234
273
  }
235
274
  } else if (keySource === "raw") {
@@ -239,7 +278,8 @@ async function runWizard() {
239
278
  mask: "*"
240
279
  })
241
280
  );
242
- privateKey = pk.trim() || null;
281
+ const trimmed = pk.trim();
282
+ privateKey = trimmed ? trimmed.startsWith("0x") ? trimmed : "0x" + trimmed : null;
243
283
  }
244
284
  const providerChoice = check(
245
285
  await select({
@@ -312,7 +352,7 @@ async function main() {
312
352
  case "setup": {
313
353
  const { cfg, terminalMode } = await runWizard();
314
354
  if (terminalMode) {
315
- const { startChatSession } = await import("./session-52D3R73Y.js");
355
+ const { startChatSession } = await import("./session-TQ2F7RWC.js");
316
356
  await startChatSession(cfg);
317
357
  } else {
318
358
  await startServer();
@@ -392,7 +432,7 @@ async function main() {
392
432
  console.log("No config. Run: moly setup");
393
433
  process.exit(1);
394
434
  }
395
- const { runDaemon } = await import("./daemon-XWJQH7IB.js");
435
+ const { runDaemon } = await import("./daemon-QQW5XDFW.js");
396
436
  await runDaemon();
397
437
  break;
398
438
  }
@@ -550,7 +590,7 @@ async function main() {
550
590
  console.log("No config. Run: moly setup");
551
591
  process.exit(1);
552
592
  }
553
- const { getTotalPosition } = await import("./position-WDLPRIE7.js");
593
+ const { getTotalPosition } = await import("./position-7UQ3RE3M.js");
554
594
  const address = args[1];
555
595
  const pos = await getTotalPosition(address);
556
596
  console.log(JSON.stringify(pos, null, 2));
@@ -561,18 +601,69 @@ async function main() {
561
601
  if (!configExists()) {
562
602
  const { cfg, terminalMode } = await runWizard();
563
603
  if (terminalMode) {
564
- const { startChatSession } = await import("./session-52D3R73Y.js");
604
+ const { startChatSession } = await import("./session-TQ2F7RWC.js");
565
605
  await startChatSession(cfg);
566
606
  } else {
567
607
  await startServer();
568
608
  }
569
609
  } else {
570
610
  const cfg = loadConfig();
571
- const { startChatSession } = await import("./session-52D3R73Y.js");
611
+ const { startChatSession } = await import("./session-TQ2F7RWC.js");
572
612
  await startChatSession(cfg);
573
613
  }
574
614
  break;
575
615
  }
616
+ // ── moly --help / help / -h ─────────────────────────────────────────
617
+ case "--help":
618
+ case "-h":
619
+ case "help": {
620
+ console.log(`
621
+ moly \u2014 Lido MCP Server CLI
622
+
623
+ Commands:
624
+ setup Run the setup wizard
625
+ config Show current configuration
626
+ reset Delete configuration
627
+ terminal Start interactive chat session
628
+ --server Start MCP server (used in AI client configs)
629
+
630
+ alert Manage price/balance alerts
631
+ add <cond> Add alert (e.g. "eth_below 2000")
632
+ list List active alerts
633
+ remove <id> Remove alert by ID
634
+ channels Configure alert channels
635
+ start Start alert daemon in background
636
+
637
+ monitor Daemon management
638
+ start Start monitor daemon
639
+ status Show daemon status
640
+ stop Stop daemon
641
+
642
+ bounds Transaction safety bounds
643
+ show Show current bounds
644
+ set Set bounds (flags: --max-stake-per-tx, --max-daily-stake, --min-eth-reserve)
645
+ reset Reset to defaults
646
+
647
+ ledger Transaction history
648
+ list List entries (--tool, --since, --limit)
649
+ stats Show statistics
650
+ export Export (--format json|csv)
651
+
652
+ position [addr] Show total staking position
653
+
654
+ help, --help Show this help
655
+ --version Show version
656
+ `);
657
+ break;
658
+ }
659
+ // ── moly --version / -v ──────────────────────────────────────────
660
+ case "--version":
661
+ case "-v": {
662
+ const { createRequire } = await import("module");
663
+ const pkg = createRequire(import.meta.url)("../package.json");
664
+ console.log(`@moly-mcp/lido v${pkg.version}`);
665
+ break;
666
+ }
576
667
  // ── moly --server (force-start, used in AI client configs) ────────
577
668
  case "--server": {
578
669
  if (!configExists()) {
@@ -589,7 +680,7 @@ async function main() {
589
680
  if (!configExists()) {
590
681
  const { cfg, terminalMode } = await runWizard();
591
682
  if (terminalMode) {
592
- const { startChatSession } = await import("./session-52D3R73Y.js");
683
+ const { startChatSession } = await import("./session-TQ2F7RWC.js");
593
684
  await startChatSession(cfg);
594
685
  } else {
595
686
  await startServer();
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  getRuntime
4
- } from "./chunk-XSQE6QAD.js";
4
+ } from "./chunk-TISPNEN6.js";
5
5
 
6
6
  // src/tools/unstake.ts
7
7
  import { parseEther, formatEther } from "viem";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  applySettingsUpdate,
4
4
  getRuntime
5
- } from "./chunk-XSQE6QAD.js";
5
+ } from "./chunk-TISPNEN6.js";
6
6
  import {
7
7
  loadConfig,
8
8
  redactedConfig
@@ -4,7 +4,7 @@ import {
4
4
  getBalance,
5
5
  getConversionRate,
6
6
  getRuntime
7
- } from "./chunk-XSQE6QAD.js";
7
+ } from "./chunk-TISPNEN6.js";
8
8
 
9
9
  // src/tools/bridge.ts
10
10
  import { formatEther, parseEther, parseAbi } from "viem";
@@ -76,24 +76,27 @@ function buildRuntime() {
76
76
  if (_resolvedAccount) return _resolvedAccount;
77
77
  if (config.ows) {
78
78
  let owsSdk;
79
- try {
80
- owsSdk = _require("@open-wallet-standard/core");
81
- } catch {
79
+ const loaders = [
80
+ () => _require("@open-wallet-standard/core"),
81
+ () => createRequire(join(homedir(), ".moly", "package.json"))("@open-wallet-standard/core"),
82
+ () => createRequire(join(homedir(), ".nvm", "versions", "node", process.version, "lib", "node_modules", "package.json"))("@open-wallet-standard/core")
83
+ ];
84
+ for (const loader of loaders) {
82
85
  try {
83
- const molyRequire = createRequire(join(homedir(), ".moly", "package.json"));
84
- owsSdk = molyRequire("@open-wallet-standard/core");
86
+ owsSdk = loader();
87
+ break;
85
88
  } catch {
86
- throw new Error("OWS SDK not installed. Run: moly setup and select OWS Wallet");
87
89
  }
88
90
  }
89
- const exported = owsSdk.exportWallet(config.ows.walletName, config.ows.passphrase);
90
- const keyHex = exported.secp256k1 ?? exported;
91
+ if (!owsSdk) throw new Error("OWS SDK not installed. Run: npm install -g @open-wallet-standard/core");
92
+ const keyHex = owsSdk.exportWallet(config.ows.walletName, config.ows.passphrase ?? void 0);
91
93
  const pk2 = keyHex.startsWith("0x") ? keyHex : "0x" + keyHex;
92
94
  _resolvedAccount = privateKeyToAccount(pk2);
93
95
  return _resolvedAccount;
94
96
  }
95
- const pk = config.privateKey;
96
- if (!pk) throw new Error("No key configured. Run: moly setup");
97
+ const rawKey = config.privateKey;
98
+ if (!rawKey) throw new Error("No key configured. Run: moly setup");
99
+ const pk = rawKey.startsWith("0x") ? rawKey : "0x" + rawKey;
97
100
  _resolvedAccount = privateKeyToAccount(pk);
98
101
  return _resolvedAccount;
99
102
  }
@@ -3,7 +3,7 @@ import {
3
3
  getProposals,
4
4
  getWithdrawalRequests,
5
5
  getWithdrawalStatus
6
- } from "./chunk-D5JID4WC.js";
6
+ } from "./chunk-6ZOV6GSP.js";
7
7
  import {
8
8
  loadAlerts,
9
9
  loadChannelConfig,
@@ -14,7 +14,7 @@ import {
14
14
  getConversionRate,
15
15
  getRewards,
16
16
  getRuntime
17
- } from "./chunk-XSQE6QAD.js";
17
+ } from "./chunk-TISPNEN6.js";
18
18
  import "./chunk-P6VFMSPM.js";
19
19
  import "./chunk-PDX44BCA.js";
20
20
 
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  getTotalPosition
4
- } from "./chunk-27PRUUR7.js";
5
- import "./chunk-XSQE6QAD.js";
4
+ } from "./chunk-F4OVF3FT.js";
5
+ import "./chunk-TISPNEN6.js";
6
6
  import "./chunk-P6VFMSPM.js";
7
7
  import "./chunk-PDX44BCA.js";
8
8
  export {
@@ -3,7 +3,7 @@ import {
3
3
  getSettings,
4
4
  stakeEth,
5
5
  updateSettings
6
- } from "../chunk-A27W633R.js";
6
+ } from "../chunk-DEQ35QKH.js";
7
7
  import {
8
8
  castVote,
9
9
  claimWithdrawals,
@@ -12,7 +12,7 @@ import {
12
12
  getWithdrawalRequests,
13
13
  getWithdrawalStatus,
14
14
  requestWithdrawal
15
- } from "../chunk-D5JID4WC.js";
15
+ } from "../chunk-6ZOV6GSP.js";
16
16
  import {
17
17
  configureAlertChannels,
18
18
  listAlerts,
@@ -26,14 +26,14 @@ import {
26
26
  getBridgeStatus,
27
27
  getL2Balance,
28
28
  getTotalPosition
29
- } from "../chunk-27PRUUR7.js";
29
+ } from "../chunk-F4OVF3FT.js";
30
30
  import {
31
31
  getBalance,
32
32
  getConversionRate,
33
33
  getRewards,
34
34
  unwrapWsteth,
35
35
  wrapSteth
36
- } from "../chunk-XSQE6QAD.js";
36
+ } from "../chunk-TISPNEN6.js";
37
37
  import {
38
38
  loadConfig
39
39
  } from "../chunk-P6VFMSPM.js";
@@ -3,7 +3,7 @@ import {
3
3
  getSettings,
4
4
  stakeEth,
5
5
  updateSettings
6
- } from "./chunk-A27W633R.js";
6
+ } from "./chunk-DEQ35QKH.js";
7
7
  import {
8
8
  castVote,
9
9
  claimWithdrawals,
@@ -12,7 +12,7 @@ import {
12
12
  getWithdrawalRequests,
13
13
  getWithdrawalStatus,
14
14
  requestWithdrawal
15
- } from "./chunk-D5JID4WC.js";
15
+ } from "./chunk-6ZOV6GSP.js";
16
16
  import {
17
17
  configureAlertChannels,
18
18
  listAlerts,
@@ -26,14 +26,14 @@ import {
26
26
  getBridgeStatus,
27
27
  getL2Balance,
28
28
  getTotalPosition
29
- } from "./chunk-27PRUUR7.js";
29
+ } from "./chunk-F4OVF3FT.js";
30
30
  import {
31
31
  getBalance,
32
32
  getConversionRate,
33
33
  getRewards,
34
34
  unwrapWsteth,
35
35
  wrapSteth
36
- } from "./chunk-XSQE6QAD.js";
36
+ } from "./chunk-TISPNEN6.js";
37
37
  import "./chunk-P6VFMSPM.js";
38
38
  import {
39
39
  loadBounds,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moly-mcp/lido",
3
- "version": "1.1.4",
3
+ "version": "1.1.6",
4
4
  "description": "Lido MCP Server — stake, unstake, wrap, govern. Works with Claude Desktop, Cursor, Windsurf, and any MCP client.",
5
5
  "license": "MIT",
6
6
  "type": "module",