dexe-mcp 0.7.1 → 0.8.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 (59) hide show
  1. package/CHANGELOG.md +106 -0
  2. package/README.md +20 -2
  3. package/dist/cli/doctor.d.ts +11 -0
  4. package/dist/cli/doctor.d.ts.map +1 -0
  5. package/dist/cli/doctor.js +44 -0
  6. package/dist/cli/doctor.js.map +1 -0
  7. package/dist/cli/init.d.ts +2 -0
  8. package/dist/cli/init.d.ts.map +1 -0
  9. package/dist/cli/init.js +306 -0
  10. package/dist/cli/init.js.map +1 -0
  11. package/dist/diag/checks.d.ts +25 -0
  12. package/dist/diag/checks.d.ts.map +1 -0
  13. package/dist/diag/checks.js +387 -0
  14. package/dist/diag/checks.js.map +1 -0
  15. package/dist/env/loader.d.ts +43 -0
  16. package/dist/env/loader.d.ts.map +1 -0
  17. package/dist/env/loader.js +121 -0
  18. package/dist/env/loader.js.map +1 -0
  19. package/dist/env/parse.d.ts +23 -0
  20. package/dist/env/parse.d.ts.map +1 -0
  21. package/dist/env/parse.js +41 -0
  22. package/dist/env/parse.js.map +1 -0
  23. package/dist/env/schema.d.ts +257 -0
  24. package/dist/env/schema.d.ts.map +1 -0
  25. package/dist/env/schema.js +240 -0
  26. package/dist/env/schema.js.map +1 -0
  27. package/dist/governor/adapter.d.ts +1 -1
  28. package/dist/governor/adapter.d.ts.map +1 -1
  29. package/dist/governor/adapter.js +2 -1
  30. package/dist/governor/adapter.js.map +1 -1
  31. package/dist/governor/tools/extras.js +14 -3
  32. package/dist/governor/tools/extras.js.map +1 -1
  33. package/dist/index.js +31 -11
  34. package/dist/index.js.map +1 -1
  35. package/dist/lib/requireEnv.d.ts +30 -0
  36. package/dist/lib/requireEnv.d.ts.map +1 -0
  37. package/dist/lib/requireEnv.js +48 -0
  38. package/dist/lib/requireEnv.js.map +1 -0
  39. package/dist/lib/signer.d.ts +8 -0
  40. package/dist/lib/signer.d.ts.map +1 -1
  41. package/dist/lib/signer.js +18 -0
  42. package/dist/lib/signer.js.map +1 -1
  43. package/dist/rpc.d.ts +8 -0
  44. package/dist/rpc.d.ts.map +1 -1
  45. package/dist/rpc.js +18 -0
  46. package/dist/rpc.js.map +1 -1
  47. package/dist/tools/doctor.d.ts +11 -0
  48. package/dist/tools/doctor.d.ts.map +1 -0
  49. package/dist/tools/doctor.js +75 -0
  50. package/dist/tools/doctor.js.map +1 -0
  51. package/dist/tools/index.d.ts.map +1 -1
  52. package/dist/tools/index.js +3 -0
  53. package/dist/tools/index.js.map +1 -1
  54. package/dist/tools/read.js +40 -10
  55. package/dist/tools/read.js.map +1 -1
  56. package/dist/tools/txSend.d.ts.map +1 -1
  57. package/dist/tools/txSend.js +18 -1
  58. package/dist/tools/txSend.js.map +1 -1
  59. package/package.json +5 -2
package/dist/index.js CHANGED
@@ -1,23 +1,43 @@
1
1
  #!/usr/bin/env node
2
2
  import { resolve, dirname } from "node:path";
3
- import { existsSync } from "node:fs";
4
3
  import { fileURLToPath } from "node:url";
5
4
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
6
5
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
7
6
  import { loadConfig } from "./config.js";
8
7
  import { registerAll } from "./tools/index.js";
9
- // Load .env from project root if present — ensures env vars reach the process
10
- // regardless of how the MCP host launches us (Claude Code drops most env vars
11
- // from its settings.json "env" block on Windows).
8
+ import { loadEnvFile, writeStartupBanner } from "./env/loader.js";
9
+ import { envKeys } from "./env/schema.js";
10
+ // Snapshot DEXE_* schema keys already in process.env BEFORE we load .env.
11
+ // Anything found here was injected by the MCP host (Claude Code's
12
+ // .claude.json `env` block) and will SHADOW the .env file —
13
+ // `process.loadEnvFile()` does NOT override pre-set keys. The startup banner
14
+ // (and dexe_doctor) surface the collision so users don't chase a phantom
15
+ // "I edited .env and nothing changed" bug.
16
+ //
17
+ // This must run BEFORE the CLI subcommand dispatch below: `npx dexe-mcp
18
+ // doctor` invoked directly from a shell needs the same env as the MCP
19
+ // startup path, otherwise the diagnostic sees an empty config.
12
20
  const __dirname = dirname(fileURLToPath(import.meta.url));
13
21
  const dotenvPath = resolve(__dirname, "..", ".env");
14
- if (existsSync(dotenvPath)) {
15
- try {
16
- process.loadEnvFile(dotenvPath);
17
- }
18
- catch {
19
- // Node < 21.7 or other issue fall through to process.env as-is
20
- }
22
+ const prevSnapshot = new Set(envKeys().filter(k => !!process.env[k]?.trim()));
23
+ const envReport = loadEnvFile(dotenvPath, prevSnapshot);
24
+ writeStartupBanner(envReport);
25
+ // CLI subcommand dispatch. `npx dexe-mcp` (no args) → MCP server.
26
+ // `npx dexe-mcp doctor` → run diagnostics and exit.
27
+ // `npx dexe-mcp init` → run the onboarding wizard and exit.
28
+ // Keeps a single bin entry instead of shipping parallel scripts.
29
+ // Subcommands must be handled BEFORE the stdio transport opens — the MCP
30
+ // host passes no args, so any argv[2] means a human/CI invoked directly.
31
+ const subcommand = process.argv[2];
32
+ if (subcommand === "doctor") {
33
+ const mod = await import("./cli/doctor.js");
34
+ await mod.run();
35
+ process.exit(0);
36
+ }
37
+ if (subcommand === "init") {
38
+ const mod = await import("./cli/init.js");
39
+ await mod.run();
40
+ process.exit(0);
21
41
  }
22
42
  async function main() {
23
43
  const config = await loadConfig();
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,8EAA8E;AAC9E,8EAA8E;AAC9E,kDAAkD;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AACpD,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;IAC3B,IAAI,CAAC;QACH,OAAO,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,iEAAiE;IACnE,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAElC,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,EACtC;QACE,YAAY,EACV,mRAAmR;KACtR,CACF,CAAC;IAEF,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE5B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,qDAAqD;IACrD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,qDAAqD,MAAM,CAAC,YAAY,GACtE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EACrC,IAAI,CACL,CAAC;AACJ,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC5B,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1E,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,GAAG,IAAI,CAAC,CAAC;IAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { type EnvKey } from "../env/schema.js";
2
+ /**
3
+ * Result of a soft env guard. `ok` carries the resolved value; the error
4
+ * branch carries both a one-line `error` and a multi-line `remediation`
5
+ * with paste-ready fixes. Tool handlers fold these into MCP `errorResult`.
6
+ *
7
+ * Modeled on the long-standing `requirePinata` pattern in
8
+ * `src/tools/ipfs.ts:129-137` so existing call sites need only a minimal
9
+ * refactor.
10
+ */
11
+ export type EnvGuardResult<T> = {
12
+ ok: T;
13
+ } | {
14
+ error: string;
15
+ remediation: string;
16
+ };
17
+ /**
18
+ * Soft env-var guard. Returns `{ ok }` only when every listed key is present
19
+ * and non-blank in `process.env`; otherwise returns a remediation hint that
20
+ * names the missing keys and the flows they unlock.
21
+ */
22
+ export declare function requireEnv<K extends EnvKey>(keys: readonly K[]): EnvGuardResult<Record<K, string>>;
23
+ /**
24
+ * Build a human-readable remediation string for a list of (possibly missing)
25
+ * env keys. Pulls per-key documentation and flow-enable metadata out of
26
+ * ENV_SPEC and tacks on the restart reminder so MCP clients don't keep
27
+ * retrying without picking up the new env.
28
+ */
29
+ export declare function hintFor(keys: readonly EnvKey[]): string;
30
+ //# sourceMappingURL=requireEnv.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requireEnv.d.ts","sourceRoot":"","sources":["../../src/lib/requireEnv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE7D;;;;;;;;GAQG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAAE,EAAE,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnF;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EACzC,IAAI,EAAE,SAAS,CAAC,EAAE,GACjB,cAAc,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAkBnC;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAevD"}
@@ -0,0 +1,48 @@
1
+ import { ENV_REGISTRY } from "../env/schema.js";
2
+ /**
3
+ * Soft env-var guard. Returns `{ ok }` only when every listed key is present
4
+ * and non-blank in `process.env`; otherwise returns a remediation hint that
5
+ * names the missing keys and the flows they unlock.
6
+ */
7
+ export function requireEnv(keys) {
8
+ const missing = [];
9
+ const out = {};
10
+ for (const k of keys) {
11
+ const v = process.env[k]?.trim();
12
+ if (!v) {
13
+ missing.push(k);
14
+ }
15
+ else {
16
+ out[k] = v;
17
+ }
18
+ }
19
+ if (missing.length > 0) {
20
+ return {
21
+ error: `Missing required env: ${missing.join(", ")}`,
22
+ remediation: hintFor(missing),
23
+ };
24
+ }
25
+ return { ok: out };
26
+ }
27
+ /**
28
+ * Build a human-readable remediation string for a list of (possibly missing)
29
+ * env keys. Pulls per-key documentation and flow-enable metadata out of
30
+ * ENV_SPEC and tacks on the restart reminder so MCP clients don't keep
31
+ * retrying without picking up the new env.
32
+ */
33
+ export function hintFor(keys) {
34
+ const parts = [];
35
+ for (const k of keys) {
36
+ const spec = ENV_REGISTRY[k];
37
+ if (!spec)
38
+ continue;
39
+ const flowHint = spec.enablesFlows?.length
40
+ ? ` (enables: ${spec.enablesFlows.join(", ")})`
41
+ : "";
42
+ parts.push(`Set ${k} in .env — ${spec.doc}${flowHint}`);
43
+ }
44
+ parts.push("After editing .env, restart the MCP server (Claude Code: quit + relaunch). " +
45
+ "Run dexe_doctor to verify the new values were picked up.");
46
+ return parts.join("\n");
47
+ }
48
+ //# sourceMappingURL=requireEnv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requireEnv.js","sourceRoot":"","sources":["../../src/lib/requireEnv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAe,MAAM,kBAAkB,CAAC;AAa7D;;;;GAIG;AACH,MAAM,UAAU,UAAU,CACxB,IAAkB;IAElB,MAAM,OAAO,GAAQ,EAAE,CAAC;IACxB,MAAM,GAAG,GAAG,EAAuB,CAAC;IACpC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;QACjC,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACb,CAAC;IACH,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO;YACL,KAAK,EAAE,yBAAyB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACpD,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC;SAC9B,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC;AACrB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CAAC,IAAuB;IAC7C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;QAC7B,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,MAAM;YACxC,CAAC,CAAC,cAAc,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;YAC/C,CAAC,CAAC,EAAE,CAAC;QACP,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,IAAI,CAAC,GAAG,GAAG,QAAQ,EAAE,CAAC,CAAC;IAC1D,CAAC;IACD,KAAK,CAAC,IAAI,CACR,6EAA6E;QAC3E,0DAA0D,CAC7D,CAAC;IACF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { Wallet } from "ethers";
2
2
  import { type DexeConfig } from "../config.js";
3
+ import { type EnvGuardResult } from "./requireEnv.js";
3
4
  /**
4
5
  * Per-chain signer cache. The private key is chain-agnostic; only the
5
6
  * provider differs per chain.
@@ -22,6 +23,13 @@ export declare class SignerManager {
22
23
  * omitted the default chain is used.
23
24
  */
24
25
  requireSigner(chainId?: number): Wallet;
26
+ /**
27
+ * Soft variant of `requireSigner` — returns a structured `{error, remediation}`
28
+ * instead of throwing when the key or RPC is missing. Hot tool paths use
29
+ * this so missing env surfaces as a clean MCP error with fix instructions
30
+ * instead of a thrown stack trace.
31
+ */
32
+ trySigner(chainId?: number): EnvGuardResult<Wallet>;
25
33
  private failNoKey;
26
34
  }
27
35
  //# sourceMappingURL=signer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../../src/lib/signer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,MAAM,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAE7D;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IACnD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAqB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;gBAExB,MAAM,EAAE,UAAU;IAK9B,SAAS,IAAI,OAAO;IAIpB,wFAAwF;IACxF,SAAS,IAAI,UAAU;IAIvB;;;OAGG;IACH,UAAU,IAAI,MAAM;IAKpB;;;OAGG;IACH,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM;IAYvC,OAAO,CAAC,SAAS;CAMlB"}
1
+ {"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../../src/lib/signer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,MAAM,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAW,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE/D;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IACnD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAqB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;gBAExB,MAAM,EAAE,UAAU;IAK9B,SAAS,IAAI,OAAO;IAIpB,wFAAwF;IACxF,SAAS,IAAI,UAAU;IAIvB;;;OAGG;IACH,UAAU,IAAI,MAAM;IAKpB;;;OAGG;IACH,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM;IAYvC;;;;;OAKG;IACH,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC;IAWnD,OAAO,CAAC,SAAS;CAMlB"}
@@ -1,5 +1,6 @@
1
1
  import { JsonRpcProvider, Wallet } from "ethers";
2
2
  import { resolveChain } from "../config.js";
3
+ import { hintFor } from "./requireEnv.js";
3
4
  /**
4
5
  * Per-chain signer cache. The private key is chain-agnostic; only the
5
6
  * provider differs per chain.
@@ -44,6 +45,23 @@ export class SignerManager {
44
45
  }
45
46
  return wallet;
46
47
  }
48
+ /**
49
+ * Soft variant of `requireSigner` — returns a structured `{error, remediation}`
50
+ * instead of throwing when the key or RPC is missing. Hot tool paths use
51
+ * this so missing env surfaces as a clean MCP error with fix instructions
52
+ * instead of a thrown stack trace.
53
+ */
54
+ trySigner(chainId) {
55
+ try {
56
+ return { ok: this.requireSigner(chainId) };
57
+ }
58
+ catch (err) {
59
+ return {
60
+ error: err instanceof Error ? err.message : String(err),
61
+ remediation: hintFor(["DEXE_PRIVATE_KEY"]),
62
+ };
63
+ }
64
+ }
47
65
  failNoKey() {
48
66
  const dexeEnvKeys = Object.keys(process.env).filter(k => k.startsWith("DEXE_")).join(", ");
49
67
  throw new Error(`DEXE_PRIVATE_KEY not set. Available DEXE_* env vars: [${dexeEnvKeys}]. Configure it in MCP server env to enable transaction signing.`);
@@ -1 +1 @@
1
- {"version":3,"file":"signer.js","sourceRoot":"","sources":["../../src/lib/signer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAE,YAAY,EAAmB,MAAM,cAAc,CAAC;AAE7D;;;GAGG;AACH,MAAM,OAAO,aAAa;IACP,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IAClC,GAAG,CAAqB;IACxB,MAAM,CAAa;IAEpC,YAAY,MAAkB;QAC5B,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,SAAS;QACP,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;IACpB,CAAC;IAED,wFAAwF;IACxF,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;;OAGG;IACH,UAAU;QACR,IAAI,CAAC,IAAI,CAAC,GAAG;YAAE,IAAI,CAAC,SAAS,EAAE,CAAC;QAChC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;IACtC,CAAC;IAED;;;OAGG;IACH,aAAa,CAAC,OAAgB;QAC5B,IAAI,CAAC,IAAI,CAAC,GAAG;YAAE,IAAI,CAAC,SAAS,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACjD,IAAI,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACnD,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YACxC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,SAAS;QACf,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3F,MAAM,IAAI,KAAK,CACb,yDAAyD,WAAW,kEAAkE,CACvI,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"signer.js","sourceRoot":"","sources":["../../src/lib/signer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAE,YAAY,EAAmB,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAuB,MAAM,iBAAiB,CAAC;AAE/D;;;GAGG;AACH,MAAM,OAAO,aAAa;IACP,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IAClC,GAAG,CAAqB;IACxB,MAAM,CAAa;IAEpC,YAAY,MAAkB;QAC5B,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,SAAS;QACP,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;IACpB,CAAC;IAED,wFAAwF;IACxF,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;;OAGG;IACH,UAAU;QACR,IAAI,CAAC,IAAI,CAAC,GAAG;YAAE,IAAI,CAAC,SAAS,EAAE,CAAC;QAChC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;IACtC,CAAC;IAED;;;OAGG;IACH,aAAa,CAAC,OAAgB;QAC5B,IAAI,CAAC,IAAI,CAAC,GAAG;YAAE,IAAI,CAAC,SAAS,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACjD,IAAI,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACnD,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YACxC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,OAAgB;QACxB,IAAI,CAAC;YACH,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;gBACvD,WAAW,EAAE,OAAO,CAAC,CAAC,kBAAkB,CAAC,CAAC;aAC3C,CAAC;QACJ,CAAC;IACH,CAAC;IAEO,SAAS;QACf,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3F,MAAM,IAAI,KAAK,CACb,yDAAyD,WAAW,kEAAkE,CACvI,CAAC;IACJ,CAAC;CACF"}
package/dist/rpc.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { JsonRpcProvider } from "ethers";
2
2
  import { type DexeConfig } from "./config.js";
3
+ import type { EnvGuardResult } from "./lib/requireEnv.js";
3
4
  /**
4
5
  * Lazy ethers v6 provider factory. Gov tools that need an RPC endpoint call
5
6
  * `requireProvider(chainId?)`; tools that don't (decode_calldata,
@@ -13,6 +14,13 @@ export declare class RpcProvider {
13
14
  private readonly cache;
14
15
  constructor(config: DexeConfig);
15
16
  requireProvider(chainId?: number): JsonRpcProvider;
17
+ /**
18
+ * Soft variant of `requireProvider` — returns a structured
19
+ * `{error, remediation}` instead of throwing when no RPC is configured
20
+ * for the requested chain. Hot read paths use this so missing env surfaces
21
+ * as a clean MCP error with fix instructions instead of a thrown stack.
22
+ */
23
+ tryProvider(chainId?: number): EnvGuardResult<JsonRpcProvider>;
16
24
  /** Returns the resolved chain id (after applying the default). Cheap. */
17
25
  resolveChainId(chainId?: number): number;
18
26
  }
package/dist/rpc.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAE5D;;;;;;;GAOG;AACH,qBAAa,WAAW;IAGV,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAsC;gBAE/B,MAAM,EAAE,UAAU;IAE/C,eAAe,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAUlD,yEAAyE;IACzE,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM;CAGzC"}
1
+ {"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D;;;;;;;GAOG;AACH,qBAAa,WAAW;IAGV,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAsC;gBAE/B,MAAM,EAAE,UAAU;IAE/C,eAAe,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAUlD;;;;;OAKG;IACH,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,cAAc,CAAC,eAAe,CAAC;IAa9D,yEAAyE;IACzE,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM;CAGzC"}
package/dist/rpc.js CHANGED
@@ -23,6 +23,24 @@ export class RpcProvider {
23
23
  }
24
24
  return provider;
25
25
  }
26
+ /**
27
+ * Soft variant of `requireProvider` — returns a structured
28
+ * `{error, remediation}` instead of throwing when no RPC is configured
29
+ * for the requested chain. Hot read paths use this so missing env surfaces
30
+ * as a clean MCP error with fix instructions instead of a thrown stack.
31
+ */
32
+ tryProvider(chainId) {
33
+ try {
34
+ return { ok: this.requireProvider(chainId) };
35
+ }
36
+ catch (err) {
37
+ return {
38
+ error: err instanceof Error ? err.message : String(err),
39
+ remediation: "Set DEXE_RPC_URL_TESTNET / DEXE_RPC_URL_MAINNET / DEXE_RPC_URL_<chainId> in .env, " +
40
+ "then restart the MCP server (Claude Code: quit + relaunch). Run dexe_doctor to verify.",
41
+ };
42
+ }
43
+ }
26
44
  /** Returns the resolved chain id (after applying the default). Cheap. */
27
45
  resolveChainId(chainId) {
28
46
  return resolveChain(this.config, chainId).chainId;
package/dist/rpc.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"rpc.js","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,YAAY,EAAmB,MAAM,aAAa,CAAC;AAE5D;;;;;;;GAOG;AACH,MAAM,OAAO,WAAW;IAGO;IAFZ,KAAK,GAAG,IAAI,GAAG,EAA2B,CAAC;IAE5D,YAA6B,MAAkB;QAAlB,WAAM,GAAN,MAAM,CAAY;IAAG,CAAC;IAEnD,eAAe,CAAC,OAAgB;QAC9B,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACjD,IAAI,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,GAAG,IAAI,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC7C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,yEAAyE;IACzE,cAAc,CAAC,OAAgB;QAC7B,OAAO,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC;IACpD,CAAC;CACF"}
1
+ {"version":3,"file":"rpc.js","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,YAAY,EAAmB,MAAM,aAAa,CAAC;AAG5D;;;;;;;GAOG;AACH,MAAM,OAAO,WAAW;IAGO;IAFZ,KAAK,GAAG,IAAI,GAAG,EAA2B,CAAC;IAE5D,YAA6B,MAAkB;QAAlB,WAAM,GAAN,MAAM,CAAY;IAAG,CAAC;IAEnD,eAAe,CAAC,OAAgB;QAC9B,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACjD,IAAI,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,GAAG,IAAI,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC7C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,OAAgB;QAC1B,IAAI,CAAC;YACH,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;gBACvD,WAAW,EACT,oFAAoF;oBACpF,wFAAwF;aAC3F,CAAC;QACJ,CAAC;IACH,CAAC;IAED,yEAAyE;IACzE,cAAc,CAAC,OAAgB;QAC7B,OAAO,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC;IACpD,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { DexeConfig } from "../config.js";
3
+ /**
4
+ * `dexe_doctor` — first stop when an MCP tool reports an env-related failure.
5
+ * Walks ENV_SPEC, runs network reachability for everything configured, and
6
+ * returns a structured report with paste-ready remediation hints.
7
+ *
8
+ * Read-only. Never broadcasts. Safe to call at session start.
9
+ */
10
+ export declare function registerDoctorTool(server: McpServer, config: DexeConfig): void;
11
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/tools/doctor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AA2B/C;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAkC9E"}
@@ -0,0 +1,75 @@
1
+ import { z } from "zod";
2
+ import { runAllChecks, } from "../diag/checks.js";
3
+ function tally(results) {
4
+ let passed = 0;
5
+ let warnings = 0;
6
+ let failures = 0;
7
+ for (const r of results) {
8
+ if (r.status === "pass")
9
+ passed++;
10
+ else if (r.status === "warn")
11
+ warnings++;
12
+ else
13
+ failures++;
14
+ }
15
+ const status = failures > 0 ? "fail" : warnings > 0 ? "warn" : "pass";
16
+ return { passed, warnings, failures, status };
17
+ }
18
+ /**
19
+ * `dexe_doctor` — first stop when an MCP tool reports an env-related failure.
20
+ * Walks ENV_SPEC, runs network reachability for everything configured, and
21
+ * returns a structured report with paste-ready remediation hints.
22
+ *
23
+ * Read-only. Never broadcasts. Safe to call at session start.
24
+ */
25
+ export function registerDoctorTool(server, config) {
26
+ server.tool("dexe_doctor", "Diagnose env-var setup. Runs presence + reachability checks (RPC, Pinata, IPFS gateway DNS, subgraph, backend) and returns a pass/warn/fail report with remediation hints. " +
27
+ "Call FIRST when the user reports an env-related failure — it pinpoints the missing or invalid value. " +
28
+ "Read-only: never broadcasts, never writes. ", {
29
+ _placeholder: z
30
+ .boolean()
31
+ .optional()
32
+ .describe("Unused; tool takes no input."),
33
+ }, async () => {
34
+ const checks = await runAllChecks({ config });
35
+ const summary = tally(checks);
36
+ const remediationSummary = checks
37
+ .filter(c => c.status !== "pass" && c.remediation)
38
+ .map(c => `${c.id}: ${c.remediation.split("\n")[0]}`);
39
+ const startupTime = new Date(Date.now() - process.uptime() * 1000).toISOString();
40
+ const structured = {
41
+ summary,
42
+ checks,
43
+ remediationSummary,
44
+ startupTime,
45
+ uptimeSec: Math.round(process.uptime()),
46
+ };
47
+ return {
48
+ content: [{ type: "text", text: renderText(structured) }],
49
+ structuredContent: structured,
50
+ };
51
+ });
52
+ }
53
+ function renderText(r) {
54
+ const lines = [];
55
+ lines.push(`dexe-mcp doctor — ${r.summary.status.toUpperCase()}: ${r.summary.passed} pass / ${r.summary.warnings} warn / ${r.summary.failures} fail`);
56
+ lines.push(`server started ${r.startupTime} (uptime ${r.uptimeSec}s). ` +
57
+ `If you just edited .env, restart Claude Code so the new values load.`);
58
+ lines.push("");
59
+ for (const c of r.checks) {
60
+ const tag = c.status === "pass" ? " OK " : c.status === "warn" ? "WARN" : "FAIL";
61
+ lines.push(` [${tag}] ${c.id} ${c.message}`);
62
+ if (c.remediation) {
63
+ for (const rl of c.remediation.split("\n")) {
64
+ lines.push(` → ${rl}`);
65
+ }
66
+ }
67
+ }
68
+ if (r.remediationSummary.length) {
69
+ lines.push("");
70
+ lines.push("To fix:");
71
+ r.remediationSummary.forEach((m, i) => lines.push(` ${i + 1}) ${m}`));
72
+ }
73
+ return lines.join("\n");
74
+ }
75
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/tools/doctor.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAmC/C;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAuCvE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAoC/C;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAyCvE"}
@@ -19,6 +19,7 @@ import { registerDaoDeployTools } from "./daoDeploy.js";
19
19
  import { registerSubgraphTools } from "./subgraph.js";
20
20
  import { registerTxTools } from "./txSend.js";
21
21
  import { registerGetConfigTool } from "./getConfig.js";
22
+ import { registerDoctorTool } from "./doctor.js";
22
23
  import { registerWalletConnectTools } from "./walletconnectStatus.js";
23
24
  import { registerFlowTools } from "./flow.js";
24
25
  import { registerMerkleTools } from "./merkle.js";
@@ -63,6 +64,8 @@ export function registerAll(server, config) {
63
64
  const wc = new WalletConnectManager(config);
64
65
  registerTxTools(server, config, signer, wc);
65
66
  registerGetConfigTool(server, config, signer);
67
+ // Diagnostics — call dexe_doctor first when env-related failures show up.
68
+ registerDoctorTool(server, config);
66
69
  registerWalletConnectTools(server, config, signer, wc);
67
70
  registerFlowTools(server, ctx, signer);
68
71
  registerOtcTools(server, ctx, signer);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,8BAA8B,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAE,iCAAiC,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,kCAAkC,EAAE,MAAM,4BAA4B,CAAC;AAChF,OAAO,EAAE,kCAAkC,EAAE,MAAM,4BAA4B,CAAC;AAChF,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,MAAiB,EAAE,MAAkB;IAC/D,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,SAAS,GAAG,IAAI,aAAa,CAAC,SAAS,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAgB,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAElE,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,uBAAuB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,gBAAgB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,gBAAgB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,qBAAqB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACnC,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,0BAA0B,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACxC,8BAA8B,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5C,iCAAiC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/C,kCAAkC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChD,kCAAkC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChD,sBAAsB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACpC,sBAAsB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACpC,qBAAqB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACnC,mBAAmB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,oBAAoB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAElC,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,EAAE,GAAG,IAAI,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC5C,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IAC5C,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,0EAA0E;IAC1E,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IACvD,iBAAiB,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IACvC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IACtC,iBAAiB,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IACvC,qBAAqB,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IAE3C,0EAA0E;IAC1E,sDAAsD;IACtD,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACxC,CAAC"}
@@ -89,7 +89,10 @@ function registerMulticall(server, rpc) {
89
89
  },
90
90
  }, async ({ calls }) => {
91
91
  try {
92
- const provider = rpc.requireProvider();
92
+ const pr = rpc.tryProvider();
93
+ if ("error" in pr)
94
+ return errorResult(`${pr.error}\n${pr.remediation}`);
95
+ const provider = pr.ok;
93
96
  const batch = calls.map((c) => {
94
97
  if (!isAddress(c.target))
95
98
  throw new Error(`Invalid target: ${c.target}`);
@@ -147,7 +150,10 @@ function registerTreasury(server, rpc) {
147
150
  if (!isAddress(holder))
148
151
  return errorResult(`Invalid holder: ${holder}`);
149
152
  try {
150
- const provider = rpc.requireProvider();
153
+ const pr = rpc.tryProvider();
154
+ if ("error" in pr)
155
+ return errorResult(`${pr.error}\n${pr.remediation}`);
156
+ const provider = pr.ok;
151
157
  const native = (await provider.getBalance(holder)).toString();
152
158
  const iface = new Interface(ERC20_ABI);
153
159
  const calls = [];
@@ -198,7 +204,10 @@ function registerValidators(server, rpc) {
198
204
  if (candidate && !isAddress(candidate))
199
205
  return errorResult(`Invalid candidate: ${candidate}`);
200
206
  try {
201
- const provider = rpc.requireProvider();
207
+ const pr = rpc.tryProvider();
208
+ if ("error" in pr)
209
+ return errorResult(`${pr.error}\n${pr.remediation}`);
210
+ const provider = pr.ok;
202
211
  const gp = new Interface(GOV_POOL_ABI);
203
212
  const v = new Interface(GOV_VALIDATORS_ABI);
204
213
  const [helpersR] = await multicall(provider, [
@@ -255,7 +264,10 @@ function registerSettings(server, rpc) {
255
264
  if (!isAddress(govPool))
256
265
  return errorResult(`Invalid govPool: ${govPool}`);
257
266
  try {
258
- const provider = rpc.requireProvider();
267
+ const pr = rpc.tryProvider();
268
+ if ("error" in pr)
269
+ return errorResult(`${pr.error}\n${pr.remediation}`);
270
+ const provider = pr.ok;
259
271
  const gp = new Interface(GOV_POOL_ABI);
260
272
  const s = new Interface(GOV_SETTINGS_ABI);
261
273
  const [helpersR] = await multicall(provider, [
@@ -312,7 +324,10 @@ function registerExpertStatus(server, rpc) {
312
324
  if (!isAddress(user))
313
325
  return errorResult(`Invalid user: ${user}`);
314
326
  try {
315
- const provider = rpc.requireProvider();
327
+ const pr = rpc.tryProvider();
328
+ if ("error" in pr)
329
+ return errorResult(`${pr.error}\n${pr.remediation}`);
330
+ const provider = pr.ok;
316
331
  const gp = new Interface(GOV_POOL_ABI);
317
332
  const babt = new Interface(BABT_ABI);
318
333
  const [expertR, nftR] = await multicall(provider, [
@@ -361,7 +376,10 @@ function registerTokenSaleTiers(server, rpc) {
361
376
  if (!isAddress(tokenSaleProposal))
362
377
  return errorResult(`Invalid tokenSaleProposal: ${tokenSaleProposal}`);
363
378
  try {
364
- const provider = rpc.requireProvider();
379
+ const pr = rpc.tryProvider();
380
+ if ("error" in pr)
381
+ return errorResult(`${pr.error}\n${pr.remediation}`);
382
+ const provider = pr.ok;
365
383
  const iface = new Interface(TOKEN_SALE_READ_ABI);
366
384
  const [countR] = await multicall(provider, [
367
385
  { target: tokenSaleProposal, iface, method: "latestTierId", args: [], allowFailure: true },
@@ -403,7 +421,10 @@ function registerTokenSaleUser(server, rpc) {
403
421
  if (!isAddress(user))
404
422
  return errorResult(`Invalid user: ${user}`);
405
423
  try {
406
- const provider = rpc.requireProvider();
424
+ const pr = rpc.tryProvider();
425
+ if ("error" in pr)
426
+ return errorResult(`${pr.error}\n${pr.remediation}`);
427
+ const provider = pr.ok;
407
428
  const iface = new Interface(TOKEN_SALE_READ_ABI);
408
429
  const [viewsR] = await multicall(provider, [
409
430
  {
@@ -442,7 +463,10 @@ function registerDistributionStatus(server, rpc) {
442
463
  if (!isAddress(voter))
443
464
  return errorResult(`Invalid voter: ${voter}`);
444
465
  try {
445
- const provider = rpc.requireProvider();
466
+ const pr = rpc.tryProvider();
467
+ if ("error" in pr)
468
+ return errorResult(`${pr.error}\n${pr.remediation}`);
469
+ const provider = pr.ok;
446
470
  const iface = new Interface(DISTRIBUTION_READ_ABI);
447
471
  const calls = [];
448
472
  for (const pid of proposalIds) {
@@ -485,7 +509,10 @@ function registerStakingInfo(server, rpc) {
485
509
  if (user && !isAddress(user))
486
510
  return errorResult(`Invalid user: ${user}`);
487
511
  try {
488
- const provider = rpc.requireProvider();
512
+ const pr = rpc.tryProvider();
513
+ if ("error" in pr)
514
+ return errorResult(`${pr.error}\n${pr.remediation}`);
515
+ const provider = pr.ok;
489
516
  const iface = new Interface(STAKING_READ_ABI);
490
517
  const baseCalls = [
491
518
  { target: stakingProposal, iface, method: "stakingsCount", args: [], allowFailure: true },
@@ -525,7 +552,10 @@ function registerPrivacyPolicyStatus(server, rpc) {
525
552
  if (!isAddress(user))
526
553
  return errorResult(`Invalid user: ${user}`);
527
554
  try {
528
- const provider = rpc.requireProvider();
555
+ const pr = rpc.tryProvider();
556
+ if ("error" in pr)
557
+ return errorResult(`${pr.error}\n${pr.remediation}`);
558
+ const provider = pr.ok;
529
559
  const iface = new Interface(USER_REGISTRY_READ_ABI);
530
560
  const [hashR, agreedR] = await multicall(provider, [
531
561
  { target: userRegistry, iface, method: "documentHash", args: [], allowFailure: true },