chain-insights 0.2.27 → 0.2.29

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/README.md CHANGED
@@ -18,6 +18,7 @@ MCP endpoint for development; hosted endpoints are set explicitly with
18
18
  | `stake_insights` | Explain Bittensor staking relationships, net stake movement, and counterparties |
19
19
  | `track_funds` | Trace victim/source funds through intermediaries to exchange deposit candidates |
20
20
  | `scam_topology` | Expand a known victim incident into reviewable scam infrastructure and label candidates |
21
+ | `usage_status` | Check the caller's public free graph query quota for today |
21
22
  | `graph_query` | Run one read-only GQL/Cypher query against a GraphRAG MCP graph layer |
22
23
  | `graph_query_batch` | Run related read-only graph queries as one MCP call |
23
24
 
@@ -101,6 +102,7 @@ Check the configured endpoint and current GraphRAG MCP capabilities:
101
102
  ```bash
102
103
  cia config get graphMcpEndpoint
103
104
  cia mcp networks
105
+ cia mcp call usage_status
104
106
  cia mcp tools --refresh
105
107
  ```
106
108
 
@@ -108,6 +110,12 @@ If network or tool discovery fails, check the endpoint and access mode first.
108
110
  The CLI can still initialize workspaces and manage cases without a reachable
109
111
  GraphRAG MCP endpoint.
110
112
 
113
+ Hosted GraphRAG MCP lets new users try `graph_query` with a small public free
114
+ quota before setting up paid access. The default public free graph_query quota
115
+ is 10 execution seconds per IP per UTC day. Use `usage_status` to see the
116
+ current caller quota. When the free quota is exhausted, prepare a wallet or use
117
+ an invited tester access key and retry.
118
+
111
119
  Open a case and run a small investigation:
112
120
 
113
121
  ```bash
@@ -182,8 +190,9 @@ Graph queries must choose the right read layer explicitly:
182
190
  | `facts` | Labels, features, risk scores, assets, and enrichment |
183
191
 
184
192
  Use `graph_query_batch` when related reads should share one call and one
185
- result envelope. Endpoint access and authentication are configured separately;
186
- see [MCP proxy](docs/mcp-proxy.md).
193
+ result envelope. Use explicit `LIMIT` and pagination in your query when you
194
+ want bounded result sets. Endpoint access and authentication are configured
195
+ separately; see [MCP proxy](docs/mcp-proxy.md).
187
196
 
188
197
  ## AML Tools
189
198
 
@@ -1,4 +1,4 @@
1
- import { a as resolveGraphMcpEndpoint } from "./client-Bfw9P9uA.mjs";
1
+ import { a as resolveGraphMcpEndpoint } from "./client-D4JE7fFF.mjs";
2
2
  //#region src/mcp/capabilities.ts
3
3
  function metadataNetworksUrl(endpoint) {
4
4
  const url = new URL(endpoint);
@@ -81,4 +81,4 @@ function formatNetworkCapabilities(document) {
81
81
  //#endregion
82
82
  export { fetchNetworkCapabilities, formatNetworkCapabilities };
83
83
 
84
- //# sourceMappingURL=capabilities-BCm-2oBt.mjs.map
84
+ //# sourceMappingURL=capabilities-BC3Y5EOi.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities-BCm-2oBt.mjs","names":[],"sources":["../src/mcp/capabilities.ts"],"sourcesContent":["import type { InvestigatorConfig } from '../config/schema.js'\nimport { resolveGraphMcpEndpoint } from './client.js'\n\nexport interface NetworkRetention {\n mode: 'full_history' | 'rolling_window' | 'expanding_then_rolling' | 'bounded_range' | 'unknown' | string\n window_days?: number\n from_block?: number\n to_block?: number\n from_timestamp?: string\n to_timestamp?: string\n started_at?: string\n rolls_after_at?: string\n current_window_seconds?: number\n}\n\nexport interface NetworkLayerCapability {\n enabled: boolean\n retention?: NetworkRetention | null\n}\n\nexport interface NetworkCapability {\n network: string\n display_name?: string\n status: string\n default?: boolean\n layers: Record<string, NetworkLayerCapability>\n tools: Record<string, string>\n coverage?: {\n from_block?: number\n to_block?: number\n from_timestamp?: string\n to_timestamp?: string\n chain_tip_block?: number\n blocks_behind_tip?: number\n }\n freshness?: {\n last_processed_at?: string\n last_successful_sync_at?: string\n max_data_age_seconds?: number\n last_processing_duration_seconds?: number\n }\n}\n\nexport interface NetworkCapabilitiesDocument {\n schema: 'chain-insights.network-capabilities.v1'\n networks: NetworkCapability[]\n}\n\nfunction metadataNetworksUrl(endpoint: string): URL {\n const url = new URL(endpoint)\n url.pathname = '/metadata/networks'\n url.search = ''\n url.hash = ''\n return url\n}\n\nexport async function fetchNetworkCapabilities(\n config: Pick<InvestigatorConfig, 'mcpAuthToken' | 'graphMcpAuthToken' | 'graphMcpMode' | 'graphMcpEndpoint' | 'mcpEndpoint'>,\n): Promise<NetworkCapabilitiesDocument> {\n const endpoint = resolveGraphMcpEndpoint(config)\n const request = metadataNetworksUrl(endpoint)\n const headers = new Headers()\n const token = config.graphMcpAuthToken?.trim() || config.mcpAuthToken?.trim()\n if (token) {\n headers.set('X-MCP-Debug-Token', token)\n headers.set('Authorization', `Bearer ${token}`)\n }\n let response: Response\n try {\n response = await fetch(request, { headers })\n } catch (err) {\n throw new Error(`network capabilities unavailable at ${request}: ${(err as Error).message}`)\n }\n if (!response.ok) {\n throw new Error(`network capabilities unavailable at ${request}: HTTP ${response.status}`)\n }\n const parsed = await response.json() as NetworkCapabilitiesDocument\n if (parsed.schema !== 'chain-insights.network-capabilities.v1' || !Array.isArray(parsed.networks)) {\n throw new Error('network capabilities response has unsupported schema')\n }\n return parsed\n}\n\nfunction layerValue(network: NetworkCapability, layer: string): string {\n const capability = network.layers[layer]\n if (!capability?.enabled) return 'no'\n return 'yes'\n}\n\nfunction availableToolsLabel(network: NetworkCapability): string {\n const tools = Object.entries(network.tools ?? {})\n .filter(([, status]) => status === 'available')\n .map(([name]) => name)\n return tools.length > 0 ? tools.join(', ') : 'none'\n}\n\nfunction shortDate(value?: string): string {\n if (!value) return ''\n return value.slice(0, 10)\n}\n\nfunction datasetLabel(network: NetworkCapability): string {\n const coverage = network.coverage\n if (!coverage) return 'unknown'\n const blockRange = coverage.from_block !== undefined && coverage.to_block !== undefined\n ? `${coverage.from_block}..${coverage.to_block}`\n : 'blocks unknown'\n const dateRange = coverage.from_timestamp && coverage.to_timestamp\n ? `${shortDate(coverage.from_timestamp)}..${shortDate(coverage.to_timestamp)}`\n : 'dates unknown'\n if (blockRange === 'blocks unknown' && dateRange === 'dates unknown') return 'unknown'\n return `${blockRange} / ${dateRange}`\n}\n\nexport function formatNetworkCapabilities(document: NetworkCapabilitiesDocument): string {\n if (document.networks.length === 0) return 'No supported networks advertised.'\n const headers = ['Network', 'Topology', 'Facts', 'Risk', 'Dataset', 'Available tools']\n const widths = [14, 10, 8, 8, 38, 64]\n const row = (values: string[]) => values.map((value, index) => value.padEnd(widths[index]!)).join(' ')\n return [\n row(headers),\n widths.map((width) => '-'.repeat(width)).join(' '),\n ...document.networks.map((network) => row([\n network.display_name || network.network,\n layerValue(network, 'topology'),\n layerValue(network, 'facts'),\n layerValue(network, 'risk'),\n datasetLabel(network),\n availableToolsLabel(network),\n ])),\n ].join('\\n')\n}\n"],"mappings":";;AAgDA,SAAS,oBAAoB,UAAuB;CAClD,MAAM,MAAM,IAAI,IAAI,QAAQ;CAC5B,IAAI,WAAW;CACf,IAAI,SAAS;CACb,IAAI,OAAO;CACX,OAAO;AACT;AAEA,eAAsB,yBACpB,QACsC;CAEtC,MAAM,UAAU,oBADC,wBAAwB,MACE,CAAC;CAC5C,MAAM,UAAU,IAAI,QAAQ;CAC5B,MAAM,QAAQ,OAAO,mBAAmB,KAAK,KAAK,OAAO,cAAc,KAAK;CAC5E,IAAI,OAAO;EACT,QAAQ,IAAI,qBAAqB,KAAK;EACtC,QAAQ,IAAI,iBAAiB,UAAU,OAAO;CAChD;CACA,IAAI;CACJ,IAAI;EACF,WAAW,MAAM,MAAM,SAAS,EAAE,QAAQ,CAAC;CAC7C,SAAS,KAAK;EACZ,MAAM,IAAI,MAAM,uCAAuC,QAAQ,IAAK,IAAc,SAAS;CAC7F;CACA,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,MAAM,uCAAuC,QAAQ,SAAS,SAAS,QAAQ;CAE3F,MAAM,SAAS,MAAM,SAAS,KAAK;CACnC,IAAI,OAAO,WAAW,4CAA4C,CAAC,MAAM,QAAQ,OAAO,QAAQ,GAC9F,MAAM,IAAI,MAAM,sDAAsD;CAExE,OAAO;AACT;AAEA,SAAS,WAAW,SAA4B,OAAuB;CAErE,IAAI,CADe,QAAQ,OAAO,QACjB,SAAS,OAAO;CACjC,OAAO;AACT;AAEA,SAAS,oBAAoB,SAAoC;CAC/D,MAAM,QAAQ,OAAO,QAAQ,QAAQ,SAAS,CAAC,CAAC,EAC7C,QAAQ,GAAG,YAAY,WAAW,WAAW,EAC7C,KAAK,CAAC,UAAU,IAAI;CACvB,OAAO,MAAM,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI;AAC/C;AAEA,SAAS,UAAU,OAAwB;CACzC,IAAI,CAAC,OAAO,OAAO;CACnB,OAAO,MAAM,MAAM,GAAG,EAAE;AAC1B;AAEA,SAAS,aAAa,SAAoC;CACxD,MAAM,WAAW,QAAQ;CACzB,IAAI,CAAC,UAAU,OAAO;CACtB,MAAM,aAAa,SAAS,eAAe,KAAA,KAAa,SAAS,aAAa,KAAA,IAC1E,GAAG,SAAS,WAAW,IAAI,SAAS,aACpC;CACJ,MAAM,YAAY,SAAS,kBAAkB,SAAS,eAClD,GAAG,UAAU,SAAS,cAAc,EAAE,IAAI,UAAU,SAAS,YAAY,MACzE;CACJ,IAAI,eAAe,oBAAoB,cAAc,iBAAiB,OAAO;CAC7E,OAAO,GAAG,WAAW,KAAK;AAC5B;AAEA,SAAgB,0BAA0B,UAA+C;CACvF,IAAI,SAAS,SAAS,WAAW,GAAG,OAAO;CAC3C,MAAM,UAAU;EAAC;EAAW;EAAY;EAAS;EAAQ;EAAW;CAAiB;CACrF,MAAM,SAAS;EAAC;EAAI;EAAI;EAAG;EAAG;EAAI;CAAE;CACpC,MAAM,OAAO,WAAqB,OAAO,KAAK,OAAO,UAAU,MAAM,OAAO,OAAO,MAAO,CAAC,EAAE,KAAK,IAAI;CACtG,OAAO;EACL,IAAI,OAAO;EACX,OAAO,KAAK,UAAU,IAAI,OAAO,KAAK,CAAC,EAAE,KAAK,IAAI;EAClD,GAAG,SAAS,SAAS,KAAK,YAAY,IAAI;GACxC,QAAQ,gBAAgB,QAAQ;GAChC,WAAW,SAAS,UAAU;GAC9B,WAAW,SAAS,OAAO;GAC3B,WAAW,SAAS,MAAM;GAC1B,aAAa,OAAO;GACpB,oBAAoB,OAAO;EAC7B,CAAC,CAAC;CACJ,EAAE,KAAK,IAAI;AACb"}
1
+ {"version":3,"file":"capabilities-BC3Y5EOi.mjs","names":[],"sources":["../src/mcp/capabilities.ts"],"sourcesContent":["import type { InvestigatorConfig } from '../config/schema.js'\nimport { resolveGraphMcpEndpoint } from './client.js'\n\nexport interface NetworkRetention {\n mode: 'full_history' | 'rolling_window' | 'expanding_then_rolling' | 'bounded_range' | 'unknown' | string\n window_days?: number\n from_block?: number\n to_block?: number\n from_timestamp?: string\n to_timestamp?: string\n started_at?: string\n rolls_after_at?: string\n current_window_seconds?: number\n}\n\nexport interface NetworkLayerCapability {\n enabled: boolean\n retention?: NetworkRetention | null\n}\n\nexport interface NetworkCapability {\n network: string\n display_name?: string\n status: string\n default?: boolean\n layers: Record<string, NetworkLayerCapability>\n tools: Record<string, string>\n coverage?: {\n from_block?: number\n to_block?: number\n from_timestamp?: string\n to_timestamp?: string\n chain_tip_block?: number\n blocks_behind_tip?: number\n }\n freshness?: {\n last_processed_at?: string\n last_successful_sync_at?: string\n max_data_age_seconds?: number\n last_processing_duration_seconds?: number\n }\n}\n\nexport interface NetworkCapabilitiesDocument {\n schema: 'chain-insights.network-capabilities.v1'\n networks: NetworkCapability[]\n}\n\nfunction metadataNetworksUrl(endpoint: string): URL {\n const url = new URL(endpoint)\n url.pathname = '/metadata/networks'\n url.search = ''\n url.hash = ''\n return url\n}\n\nexport async function fetchNetworkCapabilities(\n config: Pick<InvestigatorConfig, 'mcpAuthToken' | 'graphMcpAuthToken' | 'graphMcpMode' | 'graphMcpEndpoint' | 'mcpEndpoint'>,\n): Promise<NetworkCapabilitiesDocument> {\n const endpoint = resolveGraphMcpEndpoint(config)\n const request = metadataNetworksUrl(endpoint)\n const headers = new Headers()\n const token = config.graphMcpAuthToken?.trim() || config.mcpAuthToken?.trim()\n if (token) {\n headers.set('X-MCP-Debug-Token', token)\n headers.set('Authorization', `Bearer ${token}`)\n }\n let response: Response\n try {\n response = await fetch(request, { headers })\n } catch (err) {\n throw new Error(`network capabilities unavailable at ${request}: ${(err as Error).message}`)\n }\n if (!response.ok) {\n throw new Error(`network capabilities unavailable at ${request}: HTTP ${response.status}`)\n }\n const parsed = await response.json() as NetworkCapabilitiesDocument\n if (parsed.schema !== 'chain-insights.network-capabilities.v1' || !Array.isArray(parsed.networks)) {\n throw new Error('network capabilities response has unsupported schema')\n }\n return parsed\n}\n\nfunction layerValue(network: NetworkCapability, layer: string): string {\n const capability = network.layers[layer]\n if (!capability?.enabled) return 'no'\n return 'yes'\n}\n\nfunction availableToolsLabel(network: NetworkCapability): string {\n const tools = Object.entries(network.tools ?? {})\n .filter(([, status]) => status === 'available')\n .map(([name]) => name)\n return tools.length > 0 ? tools.join(', ') : 'none'\n}\n\nfunction shortDate(value?: string): string {\n if (!value) return ''\n return value.slice(0, 10)\n}\n\nfunction datasetLabel(network: NetworkCapability): string {\n const coverage = network.coverage\n if (!coverage) return 'unknown'\n const blockRange = coverage.from_block !== undefined && coverage.to_block !== undefined\n ? `${coverage.from_block}..${coverage.to_block}`\n : 'blocks unknown'\n const dateRange = coverage.from_timestamp && coverage.to_timestamp\n ? `${shortDate(coverage.from_timestamp)}..${shortDate(coverage.to_timestamp)}`\n : 'dates unknown'\n if (blockRange === 'blocks unknown' && dateRange === 'dates unknown') return 'unknown'\n return `${blockRange} / ${dateRange}`\n}\n\nexport function formatNetworkCapabilities(document: NetworkCapabilitiesDocument): string {\n if (document.networks.length === 0) return 'No supported networks advertised.'\n const headers = ['Network', 'Topology', 'Facts', 'Risk', 'Dataset', 'Available tools']\n const widths = [14, 10, 8, 8, 38, 64]\n const row = (values: string[]) => values.map((value, index) => value.padEnd(widths[index]!)).join(' ')\n return [\n row(headers),\n widths.map((width) => '-'.repeat(width)).join(' '),\n ...document.networks.map((network) => row([\n network.display_name || network.network,\n layerValue(network, 'topology'),\n layerValue(network, 'facts'),\n layerValue(network, 'risk'),\n datasetLabel(network),\n availableToolsLabel(network),\n ])),\n ].join('\\n')\n}\n"],"mappings":";;AAgDA,SAAS,oBAAoB,UAAuB;CAClD,MAAM,MAAM,IAAI,IAAI,QAAQ;CAC5B,IAAI,WAAW;CACf,IAAI,SAAS;CACb,IAAI,OAAO;CACX,OAAO;AACT;AAEA,eAAsB,yBACpB,QACsC;CAEtC,MAAM,UAAU,oBADC,wBAAwB,MACE,CAAC;CAC5C,MAAM,UAAU,IAAI,QAAQ;CAC5B,MAAM,QAAQ,OAAO,mBAAmB,KAAK,KAAK,OAAO,cAAc,KAAK;CAC5E,IAAI,OAAO;EACT,QAAQ,IAAI,qBAAqB,KAAK;EACtC,QAAQ,IAAI,iBAAiB,UAAU,OAAO;CAChD;CACA,IAAI;CACJ,IAAI;EACF,WAAW,MAAM,MAAM,SAAS,EAAE,QAAQ,CAAC;CAC7C,SAAS,KAAK;EACZ,MAAM,IAAI,MAAM,uCAAuC,QAAQ,IAAK,IAAc,SAAS;CAC7F;CACA,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,MAAM,uCAAuC,QAAQ,SAAS,SAAS,QAAQ;CAE3F,MAAM,SAAS,MAAM,SAAS,KAAK;CACnC,IAAI,OAAO,WAAW,4CAA4C,CAAC,MAAM,QAAQ,OAAO,QAAQ,GAC9F,MAAM,IAAI,MAAM,sDAAsD;CAExE,OAAO;AACT;AAEA,SAAS,WAAW,SAA4B,OAAuB;CAErE,IAAI,CADe,QAAQ,OAAO,QACjB,SAAS,OAAO;CACjC,OAAO;AACT;AAEA,SAAS,oBAAoB,SAAoC;CAC/D,MAAM,QAAQ,OAAO,QAAQ,QAAQ,SAAS,CAAC,CAAC,EAC7C,QAAQ,GAAG,YAAY,WAAW,WAAW,EAC7C,KAAK,CAAC,UAAU,IAAI;CACvB,OAAO,MAAM,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI;AAC/C;AAEA,SAAS,UAAU,OAAwB;CACzC,IAAI,CAAC,OAAO,OAAO;CACnB,OAAO,MAAM,MAAM,GAAG,EAAE;AAC1B;AAEA,SAAS,aAAa,SAAoC;CACxD,MAAM,WAAW,QAAQ;CACzB,IAAI,CAAC,UAAU,OAAO;CACtB,MAAM,aAAa,SAAS,eAAe,KAAA,KAAa,SAAS,aAAa,KAAA,IAC1E,GAAG,SAAS,WAAW,IAAI,SAAS,aACpC;CACJ,MAAM,YAAY,SAAS,kBAAkB,SAAS,eAClD,GAAG,UAAU,SAAS,cAAc,EAAE,IAAI,UAAU,SAAS,YAAY,MACzE;CACJ,IAAI,eAAe,oBAAoB,cAAc,iBAAiB,OAAO;CAC7E,OAAO,GAAG,WAAW,KAAK;AAC5B;AAEA,SAAgB,0BAA0B,UAA+C;CACvF,IAAI,SAAS,SAAS,WAAW,GAAG,OAAO;CAC3C,MAAM,UAAU;EAAC;EAAW;EAAY;EAAS;EAAQ;EAAW;CAAiB;CACrF,MAAM,SAAS;EAAC;EAAI;EAAI;EAAG;EAAG;EAAI;CAAE;CACpC,MAAM,OAAO,WAAqB,OAAO,KAAK,OAAO,UAAU,MAAM,OAAO,OAAO,MAAO,CAAC,EAAE,KAAK,IAAI;CACtG,OAAO;EACL,IAAI,OAAO;EACX,OAAO,KAAK,UAAU,IAAI,OAAO,KAAK,CAAC,EAAE,KAAK,IAAI;EAClD,GAAG,SAAS,SAAS,KAAK,YAAY,IAAI;GACxC,QAAQ,gBAAgB,QAAQ;GAChC,WAAW,SAAS,UAAU;GAC9B,WAAW,SAAS,OAAO;GAC3B,WAAW,SAAS,MAAM;GAC1B,aAAa,OAAO;GACpB,oBAAoB,OAAO;EAC7B,CAAC,CAAC;CACJ,EAAE,KAAK,IAAI;AACb"}
@@ -1,4 +1,4 @@
1
- const require_client = require("./client-DRJq31u_.cjs");
1
+ const require_client = require("./client-Db6IV1tv.cjs");
2
2
  //#region src/mcp/capabilities.ts
3
3
  function metadataNetworksUrl(endpoint) {
4
4
  const url = new URL(endpoint);
package/dist/cli.cjs CHANGED
@@ -73,7 +73,7 @@ function optionalScamTopologyActivityPolicy(value) {
73
73
  async function withGraphMcpClient(name, fn) {
74
74
  const { loadConfig } = await Promise.resolve().then(() => require("./config-BwVx19Og.cjs")).then((n) => n.config_exports);
75
75
  const config = await loadConfig();
76
- const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-DRJq31u_.cjs")).then((n) => n.client_exports);
76
+ const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-Db6IV1tv.cjs")).then((n) => n.client_exports);
77
77
  const paymentFetch = await createConfiguredGraphMcpFetch(config);
78
78
  const { Client } = await import("@modelcontextprotocol/sdk/client/index.js");
79
79
  const { StreamableHTTPClientTransport } = await import("@modelcontextprotocol/sdk/client/streamableHttp.js");
@@ -93,7 +93,7 @@ function printMcpTextContent(result) {
93
93
  }
94
94
  async function printNetworkCapabilities(opts) {
95
95
  const { loadConfig } = await Promise.resolve().then(() => require("./config-BwVx19Og.cjs")).then((n) => n.config_exports);
96
- const { fetchNetworkCapabilities, formatNetworkCapabilities } = await Promise.resolve().then(() => require("./capabilities-C1-Y-VZx.cjs"));
96
+ const { fetchNetworkCapabilities, formatNetworkCapabilities } = await Promise.resolve().then(() => require("./capabilities-D5PSx9Hj.cjs"));
97
97
  const document = await fetchNetworkCapabilities(await loadConfig());
98
98
  if (opts.json) console.log(JSON.stringify(document, null, 2));
99
99
  else console.log(formatNetworkCapabilities(document));
@@ -261,7 +261,7 @@ program.command("config").description("Read or write configuration values").addC
261
261
  })).addCommand(new commander.Command("set").argument("<key>", "Config key to write").argument("<value>", "Value to set").action(async (key, value) => {
262
262
  if (key === "walletPrivateKey") {
263
263
  try {
264
- const { setWalletPrivateKey } = await Promise.resolve().then(() => require("./wallet-TAlNMvIM.cjs")).then((n) => n.wallet_exports);
264
+ const { setWalletPrivateKey } = await Promise.resolve().then(() => require("./wallet-gC2jxh7j.cjs")).then((n) => n.wallet_exports);
265
265
  const address = await setWalletPrivateKey(value);
266
266
  console.log("Wallet private key encrypted and stored in ~/.chain-insights/wallet.json");
267
267
  console.log(`Wallet address: ${address}`);
@@ -285,9 +285,19 @@ program.command("config").description("Read or write configuration values").addC
285
285
  const displayed = key.toLowerCase().includes("token") ? "[redacted]" : coerced;
286
286
  console.log(`Set ${key} = ${displayed}`);
287
287
  }));
288
- program.command("wallet").description("Manage the local Base USDC payment wallet").addCommand(new commander.Command("address").description("Print the local payment wallet address").action(async () => {
288
+ program.command("wallet").description("Manage the local Base USDC payment wallet").addCommand(new commander.Command("import").description("Import a Base payment wallet").argument("<private-key>", "0x-prefixed EVM private key").action(async (privateKey) => {
289
289
  try {
290
- const { getWalletAccount } = await Promise.resolve().then(() => require("./tools-kqWI7jPU.cjs")).then((n) => n.tools_exports);
290
+ const { setWalletPrivateKey } = await Promise.resolve().then(() => require("./wallet-gC2jxh7j.cjs")).then((n) => n.wallet_exports);
291
+ const address = await setWalletPrivateKey(privateKey);
292
+ console.log(`Wallet imported: ${address}`);
293
+ console.log("Next: run `chain-insights wallet ready`");
294
+ } catch (err) {
295
+ console.error(err.message);
296
+ process.exit(1);
297
+ }
298
+ })).addCommand(new commander.Command("address").description("Print the local payment wallet address").action(async () => {
299
+ try {
300
+ const { getWalletAccount } = await Promise.resolve().then(() => require("./tools-BhTI3Lmg.cjs")).then((n) => n.tools_exports);
291
301
  const account = await getWalletAccount();
292
302
  console.log(account.address);
293
303
  } catch (err) {
@@ -296,7 +306,7 @@ program.command("wallet").description("Manage the local Base USDC payment wallet
296
306
  }
297
307
  })).addCommand(new commander.Command("balance").description("Show the local payment wallet Base USDC balance").action(async () => {
298
308
  try {
299
- const { getWalletBalanceText } = await Promise.resolve().then(() => require("./tools-kqWI7jPU.cjs")).then((n) => n.tools_exports);
309
+ const { getWalletBalanceText } = await Promise.resolve().then(() => require("./tools-BhTI3Lmg.cjs")).then((n) => n.tools_exports);
300
310
  console.log(await getWalletBalanceText());
301
311
  } catch (err) {
302
312
  console.error(err.message);
@@ -304,7 +314,7 @@ program.command("wallet").description("Manage the local Base USDC payment wallet
304
314
  }
305
315
  })).addCommand(new commander.Command("ready").description("Check and prepare the wallet for paid GraphRAG MCP calls").option("--check-only", "Only check readiness; do not submit the one-time payment setup").addOption(new commander.Option("--no-approve", "Deprecated alias for --check-only").hideHelp()).option("--payment-usdc <amount>", "USDC setup cap to prepare for paid calls", "1").addOption(new commander.Option("--approval-usdc <amount>", "Deprecated alias for --payment-usdc").hideHelp()).option("--json", "Print machine-readable readiness metadata").action(async (opts) => {
306
316
  try {
307
- const { formatWalletReadiness, parsePaymentApprovalUnits, prepareWalletForPaidCalls } = await Promise.resolve().then(() => require("./tools-kqWI7jPU.cjs")).then((n) => n.tools_exports);
317
+ const { formatWalletReadiness, parsePaymentApprovalUnits, prepareWalletForPaidCalls } = await Promise.resolve().then(() => require("./tools-BhTI3Lmg.cjs")).then((n) => n.tools_exports);
308
318
  const result = await prepareWalletForPaidCalls({
309
319
  minimumApprovalUnits: parsePaymentApprovalUnits(opts.paymentUsdc ?? opts.approvalUsdc ?? "1"),
310
320
  approve: opts.checkOnly ? false : opts.approve !== false
@@ -320,7 +330,7 @@ program.command("wallet").description("Manage the local Base USDC payment wallet
320
330
  }
321
331
  })).addCommand(new commander.Command("topup").description("Open a local browser page to top up the payment wallet").option("--no-open", "Print the top-up URL without opening a browser").option("--json", "Print machine-readable top-up metadata").action(async (opts) => {
322
332
  try {
323
- const { buildTopupInfo, getWalletAccount } = await Promise.resolve().then(() => require("./tools-kqWI7jPU.cjs")).then((n) => n.tools_exports);
333
+ const { buildTopupInfo, getWalletAccount } = await Promise.resolve().then(() => require("./tools-BhTI3Lmg.cjs")).then((n) => n.tools_exports);
324
334
  const { startTopupServer } = await Promise.resolve().then(() => require("./topup-server-DhYlOOBM.cjs")).then((n) => n.topup_server_exports);
325
335
  const account = await getWalletAccount();
326
336
  const url = await startTopupServer(account);
@@ -355,7 +365,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
355
365
  const { formatToolsTable } = await Promise.resolve().then(() => require("./format-9NLBykEL.cjs"));
356
366
  const { visibleRemoteTools } = await Promise.resolve().then(() => require("./tool-visibility-iAVQV3t0.cjs")).then((n) => n.tool_visibility_exports);
357
367
  const { loadConfig } = await Promise.resolve().then(() => require("./config-BwVx19Og.cjs")).then((n) => n.config_exports);
358
- const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-DRJq31u_.cjs")).then((n) => n.client_exports);
368
+ const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-Db6IV1tv.cjs")).then((n) => n.client_exports);
359
369
  const config = await loadConfig();
360
370
  const graphMcpEndpoint = resolveGraphMcpEndpoint(config);
361
371
  let tools = opts.refresh ? null : await loadSchema(graphMcpEndpoint);
@@ -738,7 +748,7 @@ program.command("playbook").description("Run and manage investigation playbooks"
738
748
  console.error(`Invalid --from value: "${opts.from}". Must be a positive integer.`);
739
749
  process.exit(1);
740
750
  }
741
- const { PlaybookRunner } = await Promise.resolve().then(() => require("./runner-Ckl96RcN.cjs"));
751
+ const { PlaybookRunner } = await Promise.resolve().then(() => require("./runner-BCDeBYsR.cjs"));
742
752
  await PlaybookRunner.run(definition, {
743
753
  caseId: opts.case,
744
754
  from: fromN,
package/dist/cli.mjs CHANGED
@@ -71,7 +71,7 @@ function optionalScamTopologyActivityPolicy(value) {
71
71
  async function withGraphMcpClient(name, fn) {
72
72
  const { loadConfig } = await import("./config-Drgc2HuF.mjs").then((n) => n.t);
73
73
  const config = await loadConfig();
74
- const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await import("./client-Bfw9P9uA.mjs").then((n) => n.n);
74
+ const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await import("./client-D4JE7fFF.mjs").then((n) => n.n);
75
75
  const paymentFetch = await createConfiguredGraphMcpFetch(config);
76
76
  const { Client } = await import("@modelcontextprotocol/sdk/client/index.js");
77
77
  const { StreamableHTTPClientTransport } = await import("@modelcontextprotocol/sdk/client/streamableHttp.js");
@@ -91,7 +91,7 @@ function printMcpTextContent(result) {
91
91
  }
92
92
  async function printNetworkCapabilities(opts) {
93
93
  const { loadConfig } = await import("./config-Drgc2HuF.mjs").then((n) => n.t);
94
- const { fetchNetworkCapabilities, formatNetworkCapabilities } = await import("./capabilities-BCm-2oBt.mjs");
94
+ const { fetchNetworkCapabilities, formatNetworkCapabilities } = await import("./capabilities-BC3Y5EOi.mjs");
95
95
  const document = await fetchNetworkCapabilities(await loadConfig());
96
96
  if (opts.json) console.log(JSON.stringify(document, null, 2));
97
97
  else console.log(formatNetworkCapabilities(document));
@@ -259,7 +259,7 @@ program.command("config").description("Read or write configuration values").addC
259
259
  })).addCommand(new Command("set").argument("<key>", "Config key to write").argument("<value>", "Value to set").action(async (key, value) => {
260
260
  if (key === "walletPrivateKey") {
261
261
  try {
262
- const { setWalletPrivateKey } = await import("./wallet-D8IqFRKY.mjs").then((n) => n.s);
262
+ const { setWalletPrivateKey } = await import("./wallet-BL0fJC29.mjs").then((n) => n.s);
263
263
  const address = await setWalletPrivateKey(value);
264
264
  console.log("Wallet private key encrypted and stored in ~/.chain-insights/wallet.json");
265
265
  console.log(`Wallet address: ${address}`);
@@ -283,9 +283,19 @@ program.command("config").description("Read or write configuration values").addC
283
283
  const displayed = key.toLowerCase().includes("token") ? "[redacted]" : coerced;
284
284
  console.log(`Set ${key} = ${displayed}`);
285
285
  }));
286
- program.command("wallet").description("Manage the local Base USDC payment wallet").addCommand(new Command("address").description("Print the local payment wallet address").action(async () => {
286
+ program.command("wallet").description("Manage the local Base USDC payment wallet").addCommand(new Command("import").description("Import a Base payment wallet").argument("<private-key>", "0x-prefixed EVM private key").action(async (privateKey) => {
287
287
  try {
288
- const { getWalletAccount } = await import("./tools-6emZlUwg.mjs").then((n) => n.c);
288
+ const { setWalletPrivateKey } = await import("./wallet-BL0fJC29.mjs").then((n) => n.s);
289
+ const address = await setWalletPrivateKey(privateKey);
290
+ console.log(`Wallet imported: ${address}`);
291
+ console.log("Next: run `chain-insights wallet ready`");
292
+ } catch (err) {
293
+ console.error(err.message);
294
+ process.exit(1);
295
+ }
296
+ })).addCommand(new Command("address").description("Print the local payment wallet address").action(async () => {
297
+ try {
298
+ const { getWalletAccount } = await import("./tools-v6kcdojg.mjs").then((n) => n.c);
289
299
  const account = await getWalletAccount();
290
300
  console.log(account.address);
291
301
  } catch (err) {
@@ -294,7 +304,7 @@ program.command("wallet").description("Manage the local Base USDC payment wallet
294
304
  }
295
305
  })).addCommand(new Command("balance").description("Show the local payment wallet Base USDC balance").action(async () => {
296
306
  try {
297
- const { getWalletBalanceText } = await import("./tools-6emZlUwg.mjs").then((n) => n.c);
307
+ const { getWalletBalanceText } = await import("./tools-v6kcdojg.mjs").then((n) => n.c);
298
308
  console.log(await getWalletBalanceText());
299
309
  } catch (err) {
300
310
  console.error(err.message);
@@ -302,7 +312,7 @@ program.command("wallet").description("Manage the local Base USDC payment wallet
302
312
  }
303
313
  })).addCommand(new Command("ready").description("Check and prepare the wallet for paid GraphRAG MCP calls").option("--check-only", "Only check readiness; do not submit the one-time payment setup").addOption(new Option("--no-approve", "Deprecated alias for --check-only").hideHelp()).option("--payment-usdc <amount>", "USDC setup cap to prepare for paid calls", "1").addOption(new Option("--approval-usdc <amount>", "Deprecated alias for --payment-usdc").hideHelp()).option("--json", "Print machine-readable readiness metadata").action(async (opts) => {
304
314
  try {
305
- const { formatWalletReadiness, parsePaymentApprovalUnits, prepareWalletForPaidCalls } = await import("./tools-6emZlUwg.mjs").then((n) => n.c);
315
+ const { formatWalletReadiness, parsePaymentApprovalUnits, prepareWalletForPaidCalls } = await import("./tools-v6kcdojg.mjs").then((n) => n.c);
306
316
  const result = await prepareWalletForPaidCalls({
307
317
  minimumApprovalUnits: parsePaymentApprovalUnits(opts.paymentUsdc ?? opts.approvalUsdc ?? "1"),
308
318
  approve: opts.checkOnly ? false : opts.approve !== false
@@ -318,7 +328,7 @@ program.command("wallet").description("Manage the local Base USDC payment wallet
318
328
  }
319
329
  })).addCommand(new Command("topup").description("Open a local browser page to top up the payment wallet").option("--no-open", "Print the top-up URL without opening a browser").option("--json", "Print machine-readable top-up metadata").action(async (opts) => {
320
330
  try {
321
- const { buildTopupInfo, getWalletAccount } = await import("./tools-6emZlUwg.mjs").then((n) => n.c);
331
+ const { buildTopupInfo, getWalletAccount } = await import("./tools-v6kcdojg.mjs").then((n) => n.c);
322
332
  const { startTopupServer } = await import("./topup-server-R3dNp-p8.mjs").then((n) => n.r);
323
333
  const account = await getWalletAccount();
324
334
  const url = await startTopupServer(account);
@@ -353,7 +363,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
353
363
  const { formatToolsTable } = await import("./format-Bq94jSyw.mjs");
354
364
  const { visibleRemoteTools } = await import("./tool-visibility-BHRFLXuU.mjs").then((n) => n.n);
355
365
  const { loadConfig } = await import("./config-Drgc2HuF.mjs").then((n) => n.t);
356
- const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await import("./client-Bfw9P9uA.mjs").then((n) => n.n);
366
+ const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await import("./client-D4JE7fFF.mjs").then((n) => n.n);
357
367
  const config = await loadConfig();
358
368
  const graphMcpEndpoint = resolveGraphMcpEndpoint(config);
359
369
  let tools = opts.refresh ? null : await loadSchema(graphMcpEndpoint);
@@ -736,7 +746,7 @@ program.command("playbook").description("Run and manage investigation playbooks"
736
746
  console.error(`Invalid --from value: "${opts.from}". Must be a positive integer.`);
737
747
  process.exit(1);
738
748
  }
739
- const { PlaybookRunner } = await import("./runner-C-QgZu-S.mjs");
749
+ const { PlaybookRunner } = await import("./runner-CTFK0Qcg.mjs");
740
750
  await PlaybookRunner.run(definition, {
741
751
  caseId: opts.case,
742
752
  from: fromN,