chain-insights 0.18.19 → 0.19.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 (50) hide show
  1. package/README.md +4 -3
  2. package/bin/install.cjs +27 -12
  3. package/dist/{capabilities-BR985-bW.cjs → capabilities-CZYijWbg.cjs} +34 -21
  4. package/dist/{capabilities-rLNPG-O2.mjs → capabilities-CxvK7LKZ.mjs} +32 -19
  5. package/dist/capabilities-CxvK7LKZ.mjs.map +1 -0
  6. package/dist/cli.cjs +5 -5
  7. package/dist/cli.mjs +5 -5
  8. package/dist/{client-DLqndaSv.cjs → client-Bjxo7AEa.cjs} +34 -1
  9. package/dist/{client-BD9FLUt2.mjs → client-i3WtsKA4.mjs} +35 -2
  10. package/dist/client-i3WtsKA4.mjs.map +1 -0
  11. package/dist/index.cjs +1 -1
  12. package/dist/index.d.cts.map +1 -1
  13. package/dist/index.d.mts.map +1 -1
  14. package/dist/index.mjs +1 -1
  15. package/dist/{init-HVwOeOyo.cjs → init-BR4SRTAY.cjs} +7 -7
  16. package/dist/{init-Jp_AIMZ7.mjs → init-BT3STWBv.mjs} +8 -8
  17. package/dist/init-BT3STWBv.mjs.map +1 -0
  18. package/dist/mcp-proxy.cjs +8 -28
  19. package/dist/mcp-proxy.d.cts.map +1 -1
  20. package/dist/mcp-proxy.d.mts.map +1 -1
  21. package/dist/mcp-proxy.mjs +8 -28
  22. package/dist/mcp-proxy.mjs.map +1 -1
  23. package/docs/debugging.md +2 -7
  24. package/docs/graph-query-compatibility.md +3 -1
  25. package/docs/graph-tools.md +10 -12
  26. package/docs/mcp-proxy.md +7 -8
  27. package/docs/monitoring.md +0 -2
  28. package/package.json +1 -1
  29. package/skills/chain-insights-address-risk/SKILL.md +20 -77
  30. package/skills/chain-insights-cypher/SKILL.md +85 -206
  31. package/skills/chain-insights-cypher/agents/openai.yaml +2 -2
  32. package/skills/chain-insights-schema-bittensor/SKILL.md +99 -0
  33. package/skills/chain-insights-schema-evm/SKILL.md +104 -0
  34. package/dist/capabilities-rLNPG-O2.mjs.map +0 -1
  35. package/dist/client-BD9FLUt2.mjs.map +0 -1
  36. package/dist/init-Jp_AIMZ7.mjs.map +0 -1
  37. package/skills/chain-insights-bittensor-cypher/SKILL.md +0 -240
  38. package/skills/chain-insights-bittensor-cypher/agents/openai.yaml +0 -4
  39. package/skills/chain-insights-cypher/references/gql-translation-matrix.md +0 -22
  40. package/skills/chain-insights-cypher/references/memgraph-examples.md +0 -188
  41. package/skills/chain-insights-developer-experience/SKILL.md +0 -140
  42. package/skills/chain-insights-investigation/SKILL.md +0 -168
  43. package/skills/chain-insights-investigation/agents/openai.yaml +0 -4
  44. package/skills/chain-insights-investigation/scripts/run-target-uat.sh +0 -179
  45. package/skills/chain-insights-monitoring/SKILL.md +0 -160
  46. package/skills/chain-insights-monitoring/references/pm2-scheduling.md +0 -100
  47. package/skills/ci-status/SKILL.md +0 -39
  48. package/skills/test-chain-insights-graph/SKILL.md +0 -110
  49. package/skills/test-chain-insights-graph/agents/openai.yaml +0 -4
  50. package/skills/test-chain-insights-graph/scripts/run-uat.sh +0 -600
package/README.md CHANGED
@@ -179,9 +179,10 @@ on `:Address` without an exact address must scope itself with
179
179
  database and `Address` carries no `network` property at all. See
180
180
  [Graph query compatibility](docs/graph-query-compatibility.md).
181
181
 
182
- Agent installs include `chain-insights-cypher` for generic layer-aware
183
- GQL/Cypher work and `chain-insights-bittensor-cypher` for Bittensor-specific
184
- schema notes and examples (the bundled devkit serves a Bittensor fixture).
182
+ Agent installs include `chain-insights-address-risk` for one-address
183
+ screens, `chain-insights-cypher` for graph-query dialect rules,
184
+ `chain-insights-schema-evm` for the EVM / Robinhood graph map, and
185
+ `chain-insights-schema-bittensor` for the Bittensor graph map.
185
186
 
186
187
  ## Billing: Billable Units
187
188
 
package/bin/install.cjs CHANGED
@@ -39,6 +39,20 @@ const homeDir = os.homedir();
39
39
  const dataDir = path.join(homeDir, '.chain-insights');
40
40
  const configPath = path.join(dataDir, 'config.json');
41
41
  const srcSkillsDir = path.join(__dirname, '..', 'skills');
42
+ const PUBLIC_SKILL_NAMES = Object.freeze([
43
+ 'chain-insights-address-risk',
44
+ 'chain-insights-cypher',
45
+ 'chain-insights-schema-bittensor',
46
+ 'chain-insights-schema-evm',
47
+ ]);
48
+ const RETIRED_SKILL_NAMES = Object.freeze([
49
+ 'chain-insights-bittensor-cypher',
50
+ 'chain-insights-developer-experience',
51
+ 'chain-insights-investigation',
52
+ 'chain-insights-monitoring',
53
+ 'ci-status',
54
+ 'test-chain-insights-graph',
55
+ ]);
42
56
 
43
57
  // Determine skills targets
44
58
  const skillsTargets = [];
@@ -51,16 +65,14 @@ if (hasLocal) skillsTargets.push({ name: 'Local Claude commands', dir: path.join
51
65
 
52
66
  function copyCommandsAsClaudeSkills(srcDir, targetDir) {
53
67
  if (!fs.existsSync(srcDir)) {
54
- console.error(`Skills source not found: ${srcDir}`);
55
- return;
68
+ throw new Error(`Skills source not found: ${srcDir}`);
56
69
  }
57
70
 
58
71
  fs.mkdirSync(targetDir, { recursive: true });
59
72
 
60
- // NOTE: do NOT blanket-delete by prefix here. The target is a shared skills
61
- // directory that may hold the user's own skills (including unrelated `ci-*`
62
- // ones). Clean reinstall is handled per shipped skill below — each skill dir
63
- // we ship is removed and recopied, and nothing else is touched.
73
+ // The target is shared with user-owned skills. Remove only the exact retired
74
+ // names from older Chain Insights releases, then replace the reviewed set.
75
+ // Never delete by prefix or enumerate arbitrary source directories.
64
76
 
65
77
  const copyTree = (src, dest) => {
66
78
  const stat = fs.statSync(src);
@@ -76,13 +88,16 @@ function copyCommandsAsClaudeSkills(srcDir, targetDir) {
76
88
  }
77
89
  };
78
90
 
79
- // Recurse into skills/ directory; each subdirectory becomes a skill dir.
80
- const skillDirs = fs.readdirSync(srcDir, { withFileTypes: true })
81
- .filter(e => e.isDirectory());
91
+ for (const skillName of RETIRED_SKILL_NAMES) {
92
+ fs.rmSync(path.join(targetDir, skillName), { recursive: true, force: true });
93
+ }
82
94
 
83
- for (const skillDir of skillDirs) {
84
- const skillSrc = path.join(srcDir, skillDir.name);
85
- const skillDest = path.join(targetDir, skillDir.name);
95
+ for (const skillName of PUBLIC_SKILL_NAMES) {
96
+ const skillSrc = path.join(srcDir, skillName);
97
+ const skillDest = path.join(targetDir, skillName);
98
+ if (!fs.existsSync(skillSrc) || !fs.statSync(skillSrc).isDirectory()) {
99
+ throw new Error(`Reviewed skill source not found: ${skillSrc}`);
100
+ }
86
101
  fs.rmSync(skillDest, { recursive: true, force: true });
87
102
  copyTree(skillSrc, skillDest);
88
103
  }
@@ -1,12 +1,12 @@
1
1
  const require_rolldown_runtime = require("./rolldown-runtime-DakpK96I.cjs");
2
- const require_client = require("./client-DLqndaSv.cjs");
2
+ const require_client = require("./client-Bjxo7AEa.cjs");
3
3
  //#region src/mcp/capabilities.ts
4
4
  var capabilities_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
5
5
  PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS: () => PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS,
6
6
  fetchNetworkCapabilities: () => fetchNetworkCapabilities,
7
- formatNetworkCapabilities: () => formatNetworkCapabilities
7
+ formatNetworkCapabilities: () => formatNetworkCapabilities,
8
+ mirrorGraphNetworkCapabilities: () => mirrorGraphNetworkCapabilities
8
9
  });
9
- const ROBINHOOD_SEMANTIC_NETWORKS = /* @__PURE__ */ new Set(["robinhood"]);
10
10
  const PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS = {
11
11
  aml_address_risk: "available",
12
12
  graph_query: "available",
@@ -17,22 +17,35 @@ const PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS = {
17
17
  wallet_balance: "available"
18
18
  };
19
19
  const AVAILABLE_TOOLS_PER_LINE = 3;
20
- function publicNetworkCapabilities(document) {
21
- const source = document.networks.find((network) => ROBINHOOD_SEMANTIC_NETWORKS.has(network.network));
20
+ function isRecord(value) {
21
+ return typeof value === "object" && value !== null && !Array.isArray(value);
22
+ }
23
+ function advertisedNetwork(raw) {
24
+ if (!isRecord(raw) || typeof raw.network !== "string" || raw.network.trim() === "") return null;
25
+ const network = raw.network.trim();
26
+ const capability = {
27
+ network,
28
+ display_name: typeof raw.display_name === "string" && raw.display_name.trim() !== "" ? raw.display_name : network,
29
+ status: typeof raw.status === "string" && raw.status.trim() !== "" ? raw.status : "live",
30
+ layers: {},
31
+ tools: { ...PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS }
32
+ };
33
+ if (raw.default === true) capability.default = true;
34
+ if (raw.default === false) capability.default = false;
35
+ if (isRecord(raw.coverage)) capability.coverage = raw.coverage;
36
+ if (isRecord(raw.freshness)) capability.freshness = raw.freshness;
37
+ return capability;
38
+ }
39
+ /** Repeat GraphRAG's network list. CIA does not add, drop, or invent names. */
40
+ function mirrorGraphNetworkCapabilities(document) {
22
41
  return {
23
42
  schema: "chain-insights.network-capabilities.v1",
24
- networks: source ? [{
25
- network: "robinhood",
26
- display_name: "Robinhood",
27
- status: source.status || "live",
28
- default: source.default !== false,
29
- layers: {},
30
- ...source.coverage ? { coverage: source.coverage } : {},
31
- ...source.freshness ? { freshness: source.freshness } : {},
32
- tools: PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS
33
- }] : []
43
+ networks: document.networks.map((network) => advertisedNetwork(network)).filter((network) => network !== null)
34
44
  };
35
45
  }
46
+ function publicNetworkCapabilities(document) {
47
+ return mirrorGraphNetworkCapabilities(document);
48
+ }
36
49
  function metadataNetworksUrl(endpoint) {
37
50
  const url = new URL(endpoint);
38
51
  url.pathname = "/metadata/networks";
@@ -57,10 +70,10 @@ async function fetchNetworkCapabilities(config) {
57
70
  return publicNetworkCapabilities(parsed);
58
71
  }
59
72
  function availableTools(network) {
60
- const effectiveTools = ROBINHOOD_SEMANTIC_NETWORKS.has(network.network) ? {
73
+ const effectiveTools = {
61
74
  ...network.tools ?? {},
62
75
  ...PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS
63
- } : network.tools ?? {};
76
+ };
64
77
  return Object.entries(effectiveTools).filter(([, status]) => status === "available").map(([name]) => name).sort();
65
78
  }
66
79
  function availableToolLines(network) {
@@ -111,15 +124,15 @@ function formatNetworkCapabilities(document) {
111
124
  ].join("\n");
112
125
  }
113
126
  //#endregion
114
- Object.defineProperty(exports, "PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS", {
127
+ Object.defineProperty(exports, "capabilities_exports", {
115
128
  enumerable: true,
116
129
  get: function() {
117
- return PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS;
130
+ return capabilities_exports;
118
131
  }
119
132
  });
120
- Object.defineProperty(exports, "capabilities_exports", {
133
+ Object.defineProperty(exports, "mirrorGraphNetworkCapabilities", {
121
134
  enumerable: true,
122
135
  get: function() {
123
- return capabilities_exports;
136
+ return mirrorGraphNetworkCapabilities;
124
137
  }
125
138
  });
@@ -1,12 +1,12 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
- import { a as resolveGraphMcpEndpoint, n as applyMcpAuthHeaders } from "./client-BD9FLUt2.mjs";
2
+ import { a as resolveGraphMcpEndpoint, n as applyMcpAuthHeaders } from "./client-i3WtsKA4.mjs";
3
3
  //#region src/mcp/capabilities.ts
4
4
  var capabilities_exports = /* @__PURE__ */ __exportAll({
5
5
  PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS: () => PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS,
6
6
  fetchNetworkCapabilities: () => fetchNetworkCapabilities,
7
- formatNetworkCapabilities: () => formatNetworkCapabilities
7
+ formatNetworkCapabilities: () => formatNetworkCapabilities,
8
+ mirrorGraphNetworkCapabilities: () => mirrorGraphNetworkCapabilities
8
9
  });
9
- const ROBINHOOD_SEMANTIC_NETWORKS = /* @__PURE__ */ new Set(["robinhood"]);
10
10
  const PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS = {
11
11
  aml_address_risk: "available",
12
12
  graph_query: "available",
@@ -17,22 +17,35 @@ const PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS = {
17
17
  wallet_balance: "available"
18
18
  };
19
19
  const AVAILABLE_TOOLS_PER_LINE = 3;
20
- function publicNetworkCapabilities(document) {
21
- const source = document.networks.find((network) => ROBINHOOD_SEMANTIC_NETWORKS.has(network.network));
20
+ function isRecord(value) {
21
+ return typeof value === "object" && value !== null && !Array.isArray(value);
22
+ }
23
+ function advertisedNetwork(raw) {
24
+ if (!isRecord(raw) || typeof raw.network !== "string" || raw.network.trim() === "") return null;
25
+ const network = raw.network.trim();
26
+ const capability = {
27
+ network,
28
+ display_name: typeof raw.display_name === "string" && raw.display_name.trim() !== "" ? raw.display_name : network,
29
+ status: typeof raw.status === "string" && raw.status.trim() !== "" ? raw.status : "live",
30
+ layers: {},
31
+ tools: { ...PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS }
32
+ };
33
+ if (raw.default === true) capability.default = true;
34
+ if (raw.default === false) capability.default = false;
35
+ if (isRecord(raw.coverage)) capability.coverage = raw.coverage;
36
+ if (isRecord(raw.freshness)) capability.freshness = raw.freshness;
37
+ return capability;
38
+ }
39
+ /** Repeat GraphRAG's network list. CIA does not add, drop, or invent names. */
40
+ function mirrorGraphNetworkCapabilities(document) {
22
41
  return {
23
42
  schema: "chain-insights.network-capabilities.v1",
24
- networks: source ? [{
25
- network: "robinhood",
26
- display_name: "Robinhood",
27
- status: source.status || "live",
28
- default: source.default !== false,
29
- layers: {},
30
- ...source.coverage ? { coverage: source.coverage } : {},
31
- ...source.freshness ? { freshness: source.freshness } : {},
32
- tools: PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS
33
- }] : []
43
+ networks: document.networks.map((network) => advertisedNetwork(network)).filter((network) => network !== null)
34
44
  };
35
45
  }
46
+ function publicNetworkCapabilities(document) {
47
+ return mirrorGraphNetworkCapabilities(document);
48
+ }
36
49
  function metadataNetworksUrl(endpoint) {
37
50
  const url = new URL(endpoint);
38
51
  url.pathname = "/metadata/networks";
@@ -57,10 +70,10 @@ async function fetchNetworkCapabilities(config) {
57
70
  return publicNetworkCapabilities(parsed);
58
71
  }
59
72
  function availableTools(network) {
60
- const effectiveTools = ROBINHOOD_SEMANTIC_NETWORKS.has(network.network) ? {
73
+ const effectiveTools = {
61
74
  ...network.tools ?? {},
62
75
  ...PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS
63
- } : network.tools ?? {};
76
+ };
64
77
  return Object.entries(effectiveTools).filter(([, status]) => status === "available").map(([name]) => name).sort();
65
78
  }
66
79
  function availableToolLines(network) {
@@ -111,6 +124,6 @@ function formatNetworkCapabilities(document) {
111
124
  ].join("\n");
112
125
  }
113
126
  //#endregion
114
- export { capabilities_exports as n, PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS as t };
127
+ export { mirrorGraphNetworkCapabilities as n, capabilities_exports as t };
115
128
 
116
- //# sourceMappingURL=capabilities-rLNPG-O2.mjs.map
129
+ //# sourceMappingURL=capabilities-CxvK7LKZ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities-CxvK7LKZ.mjs","names":[],"sources":["../src/mcp/capabilities.ts"],"sourcesContent":["import type { InvestigatorConfig } from '../config/schema.js'\nimport { applyMcpAuthHeaders, resolveGraphMcpEndpoint } from './client.js'\n\nexport interface NetworkTopologyLayer {\n enabled: boolean\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}\n\nexport interface NetworkLayerCapability {\n enabled: boolean\n live?: NetworkTopologyLayer\n archive?: NetworkTopologyLayer\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\nexport const PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS = {\n aml_address_risk: 'available',\n graph_query: 'available',\n graph_query_batch: 'available',\n meta_network_capabilities: 'available',\n meta_usage_status: 'available',\n meta_help: 'available',\n wallet_balance: 'available',\n} as const\nconst AVAILABLE_TOOLS_PER_LINE = 3\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction advertisedNetwork(raw: unknown): NetworkCapability | null {\n if (!isRecord(raw) || typeof raw.network !== 'string' || raw.network.trim() === '') {\n return null\n }\n const network = raw.network.trim()\n const capability: NetworkCapability = {\n network,\n display_name: typeof raw.display_name === 'string' && raw.display_name.trim() !== ''\n ? raw.display_name\n : network,\n status: typeof raw.status === 'string' && raw.status.trim() !== '' ? raw.status : 'live',\n layers: {},\n tools: { ...PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS },\n }\n if (raw.default === true) capability.default = true\n if (raw.default === false) capability.default = false\n if (isRecord(raw.coverage)) capability.coverage = raw.coverage as NetworkCapability['coverage']\n if (isRecord(raw.freshness)) capability.freshness = raw.freshness as NetworkCapability['freshness']\n return capability\n}\n\n/** Repeat GraphRAG's network list. CIA does not add, drop, or invent names. */\nexport function mirrorGraphNetworkCapabilities(\n document: { networks: unknown[] },\n): NetworkCapabilitiesDocument {\n return {\n schema: 'chain-insights.network-capabilities.v1',\n networks: document.networks\n .map((network) => advertisedNetwork(network))\n .filter((network): network is NetworkCapability => network !== null),\n }\n}\n\nfunction publicNetworkCapabilities(document: NetworkCapabilitiesDocument): NetworkCapabilitiesDocument {\n return mirrorGraphNetworkCapabilities(document)\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, 'graphMcpAuthToken' | 'graphMcpMode' | 'graphMcpEndpoint'>,\n): Promise<NetworkCapabilitiesDocument> {\n const endpoint = resolveGraphMcpEndpoint(config)\n const request = metadataNetworksUrl(endpoint)\n const headers = new Headers()\n const token = config.graphMcpAuthToken?.trim()\n if (token) {\n applyMcpAuthHeaders(headers, 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 publicNetworkCapabilities(parsed)\n}\n\nfunction availableTools(network: NetworkCapability): string[] {\n const effectiveTools = {\n ...(network.tools ?? {}),\n ...PUBLIC_CHAIN_INSIGHTS_TOOL_STATUS,\n }\n const tools = Object.entries(effectiveTools)\n .filter(([, status]) => status === 'available')\n .map(([name]) => name)\n return tools.sort()\n}\n\nfunction availableToolLines(network: NetworkCapability): string[] {\n const tools = availableTools(network)\n if (tools.length === 0) return ['none']\n const lines: string[] = []\n for (let index = 0; index < tools.length; index += AVAILABLE_TOOLS_PER_LINE) {\n lines.push(tools.slice(index, index + AVAILABLE_TOOLS_PER_LINE).join(', '))\n }\n return lines\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 : ''\n if (blockRange === 'blocks unknown' && dateRange === '') return 'unknown'\n if (blockRange === 'blocks unknown') return dateRange\n if (dateRange === '') return blockRange\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', 'Dataset', 'Available tools']\n const widths = [14, 38, 64]\n const row = (values: string[]) => values.map((value, index) => value.padEnd(widths[index]!)).join(' ')\n const networkRows = document.networks.flatMap((network) => {\n const toolLines = availableToolLines(network)\n return toolLines.map((toolLine, index) => row([\n index === 0 ? network.display_name || network.network : '',\n index === 0 ? datasetLabel(network) : '',\n toolLine,\n ]))\n })\n return [\n row(headers),\n widths.map((width) => '-'.repeat(width)).join(' '),\n ...networkRows,\n ].join('\\n')\n}\n"],"mappings":";;;;;;;;;AAiDA,MAAa,oCAAoC;CAC/C,kBAAkB;CAClB,aAAa;CACb,mBAAmB;CACnB,2BAA2B;CAC3B,mBAAmB;CACnB,WAAW;CACX,gBAAgB;AAClB;AACA,MAAM,2BAA2B;AAEjC,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,kBAAkB,KAAwC;CACjE,IAAI,CAAC,SAAS,GAAG,KAAK,OAAO,IAAI,YAAY,YAAY,IAAI,QAAQ,KAAK,MAAM,IAC9E,OAAO;CAET,MAAM,UAAU,IAAI,QAAQ,KAAK;CACjC,MAAM,aAAgC;EACpC;EACA,cAAc,OAAO,IAAI,iBAAiB,YAAY,IAAI,aAAa,KAAK,MAAM,KAC9E,IAAI,eACJ;EACJ,QAAQ,OAAO,IAAI,WAAW,YAAY,IAAI,OAAO,KAAK,MAAM,KAAK,IAAI,SAAS;EAClF,QAAQ,CAAC;EACT,OAAO,EAAE,GAAG,kCAAkC;CAChD;CACA,IAAI,IAAI,YAAY,MAAM,WAAW,UAAU;CAC/C,IAAI,IAAI,YAAY,OAAO,WAAW,UAAU;CAChD,IAAI,SAAS,IAAI,QAAQ,GAAG,WAAW,WAAW,IAAI;CACtD,IAAI,SAAS,IAAI,SAAS,GAAG,WAAW,YAAY,IAAI;CACxD,OAAO;AACT;;AAGA,SAAgB,+BACd,UAC6B;CAC7B,OAAO;EACL,QAAQ;EACR,UAAU,SAAS,SAChB,KAAK,YAAY,kBAAkB,OAAO,CAAC,CAAC,CAC5C,QAAQ,YAA0C,YAAY,IAAI;CACvE;AACF;AAEA,SAAS,0BAA0B,UAAoE;CACrG,OAAO,+BAA+B,QAAQ;AAChD;AAEA,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;CAC7C,IAAI,OACF,oBAAoB,SAAS,KAAK;CAEpC,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,0BAA0B,MAAM;AACzC;AAEA,SAAS,eAAe,SAAsC;CAC5D,MAAM,iBAAiB;EACrB,GAAI,QAAQ,SAAS,CAAC;EACtB,GAAG;CACL;CAIA,OAHc,OAAO,QAAQ,cAAc,CAAC,CACzC,QAAQ,GAAG,YAAY,WAAW,WAAW,CAAC,CAC9C,KAAK,CAAC,UAAU,IACR,CAAC,CAAC,KAAK;AACpB;AAEA,SAAS,mBAAmB,SAAsC;CAChE,MAAM,QAAQ,eAAe,OAAO;CACpC,IAAI,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM;CACtC,MAAM,QAAkB,CAAC;CACzB,KAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,0BACjD,MAAM,KAAK,MAAM,MAAM,OAAO,QAAQ,wBAAwB,CAAC,CAAC,KAAK,IAAI,CAAC;CAE5E,OAAO;AACT;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,IAAI,OAAO;CAChE,IAAI,eAAe,kBAAkB,OAAO;CAC5C,IAAI,cAAc,IAAI,OAAO;CAC7B,OAAO,GAAG,WAAW,KAAK;AAC5B;AAEA,SAAgB,0BAA0B,UAA+C;CACvF,IAAI,SAAS,SAAS,WAAW,GAAG,OAAO;CAC3C,MAAM,UAAU;EAAC;EAAW;EAAW;CAAiB;CACxD,MAAM,SAAS;EAAC;EAAI;EAAI;CAAE;CAC1B,MAAM,OAAO,WAAqB,OAAO,KAAK,OAAO,UAAU,MAAM,OAAO,OAAO,MAAO,CAAC,CAAC,CAAC,KAAK,IAAI;CACtG,MAAM,cAAc,SAAS,SAAS,SAAS,YAAY;EAEzD,OADkB,mBAAmB,OACtB,CAAC,CAAC,KAAK,UAAU,UAAU,IAAI;GAC5C,UAAU,IAAI,QAAQ,gBAAgB,QAAQ,UAAU;GACxD,UAAU,IAAI,aAAa,OAAO,IAAI;GACtC;EACF,CAAC,CAAC;CACJ,CAAC;CACD,OAAO;EACL,IAAI,OAAO;EACX,OAAO,KAAK,UAAU,IAAI,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI;EAClD,GAAG;CACL,CAAC,CAAC,KAAK,IAAI;AACb"}
package/dist/cli.cjs CHANGED
@@ -52,7 +52,7 @@ function runInstaller(flag) {
52
52
  async function withGraphMcpClient(name, fn) {
53
53
  const { loadConfig } = await Promise.resolve().then(() => require("./config-DE0dUT3P.cjs")).then((n) => n.config_exports);
54
54
  const config = await loadConfig();
55
- const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-DLqndaSv.cjs")).then((n) => n.client_exports);
55
+ const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-Bjxo7AEa.cjs")).then((n) => n.client_exports);
56
56
  const paymentFetch = await createConfiguredGraphMcpFetch(config);
57
57
  const { Client } = await import("@modelcontextprotocol/sdk/client/index.js");
58
58
  const { StreamableHTTPClientTransport } = await import("@modelcontextprotocol/sdk/client/streamableHttp.js");
@@ -71,7 +71,7 @@ async function withGraphMcpClient(name, fn) {
71
71
  }
72
72
  async function printNetworkCapabilities(opts) {
73
73
  const { loadConfig } = await Promise.resolve().then(() => require("./config-DE0dUT3P.cjs")).then((n) => n.config_exports);
74
- const { fetchNetworkCapabilities, formatNetworkCapabilities } = await Promise.resolve().then(() => require("./capabilities-BR985-bW.cjs")).then((n) => n.capabilities_exports);
74
+ const { fetchNetworkCapabilities, formatNetworkCapabilities } = await Promise.resolve().then(() => require("./capabilities-CZYijWbg.cjs")).then((n) => n.capabilities_exports);
75
75
  const document = await fetchNetworkCapabilities(await loadConfig());
76
76
  if (opts.json) console.log(JSON.stringify(document, null, 2));
77
77
  else console.log(formatNetworkCapabilities(document));
@@ -222,7 +222,7 @@ program.command("access-key").description("Configure Chain Insights Graph test a
222
222
  }));
223
223
  program.command("init").description("Initialize an investigation workspace").argument("[dir]", "Workspace directory to initialize", ".").option("--force", "Overwrite existing workspace files").action(async (dir, opts) => {
224
224
  try {
225
- const { initWorkspace } = await Promise.resolve().then(() => require("./init-HVwOeOyo.cjs"));
225
+ const { initWorkspace } = await Promise.resolve().then(() => require("./init-BR4SRTAY.cjs"));
226
226
  const result = await initWorkspace({
227
227
  targetDir: dir,
228
228
  force: opts.force
@@ -361,7 +361,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
361
361
  const { formatToolsTable } = await Promise.resolve().then(() => require("./format-9NLBykEL.cjs"));
362
362
  const { visibleRemoteTools } = await Promise.resolve().then(() => require("./tool-visibility-DMIEexib.cjs")).then((n) => n.tool_visibility_exports);
363
363
  const { loadConfig } = await Promise.resolve().then(() => require("./config-DE0dUT3P.cjs")).then((n) => n.config_exports);
364
- const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-DLqndaSv.cjs")).then((n) => n.client_exports);
364
+ const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-Bjxo7AEa.cjs")).then((n) => n.client_exports);
365
365
  const config = await loadConfig();
366
366
  const graphMcpEndpoint = resolveGraphMcpEndpoint(config);
367
367
  let tools = opts.refresh ? null : await loadSchema(graphMcpEndpoint);
@@ -431,7 +431,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
431
431
  } catch (err) {
432
432
  const { isMissingUsageStatusToolError, primitiveBackendUsageStatus, usageStatusText } = await Promise.resolve().then(() => require("./usage-status-H1xgCu99.cjs")).then((n) => n.usage_status_exports);
433
433
  if (!isMissingUsageStatusToolError(err)) throw err;
434
- const { resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-DLqndaSv.cjs")).then((n) => n.client_exports);
434
+ const { resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-Bjxo7AEa.cjs")).then((n) => n.client_exports);
435
435
  console.log(usageStatusText(primitiveBackendUsageStatus(resolveGraphMcpEndpoint(config))));
436
436
  }
437
437
  return;
package/dist/cli.mjs CHANGED
@@ -50,7 +50,7 @@ function runInstaller(flag) {
50
50
  async function withGraphMcpClient(name, fn) {
51
51
  const { loadConfig } = await import("./config-DA6KRx60.mjs").then((n) => n.t);
52
52
  const config = await loadConfig();
53
- const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await import("./client-BD9FLUt2.mjs").then((n) => n.r);
53
+ const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await import("./client-i3WtsKA4.mjs").then((n) => n.r);
54
54
  const paymentFetch = await createConfiguredGraphMcpFetch(config);
55
55
  const { Client } = await import("@modelcontextprotocol/sdk/client/index.js");
56
56
  const { StreamableHTTPClientTransport } = await import("@modelcontextprotocol/sdk/client/streamableHttp.js");
@@ -69,7 +69,7 @@ async function withGraphMcpClient(name, fn) {
69
69
  }
70
70
  async function printNetworkCapabilities(opts) {
71
71
  const { loadConfig } = await import("./config-DA6KRx60.mjs").then((n) => n.t);
72
- const { fetchNetworkCapabilities, formatNetworkCapabilities } = await import("./capabilities-rLNPG-O2.mjs").then((n) => n.n);
72
+ const { fetchNetworkCapabilities, formatNetworkCapabilities } = await import("./capabilities-CxvK7LKZ.mjs").then((n) => n.t);
73
73
  const document = await fetchNetworkCapabilities(await loadConfig());
74
74
  if (opts.json) console.log(JSON.stringify(document, null, 2));
75
75
  else console.log(formatNetworkCapabilities(document));
@@ -220,7 +220,7 @@ program.command("access-key").description("Configure Chain Insights Graph test a
220
220
  }));
221
221
  program.command("init").description("Initialize an investigation workspace").argument("[dir]", "Workspace directory to initialize", ".").option("--force", "Overwrite existing workspace files").action(async (dir, opts) => {
222
222
  try {
223
- const { initWorkspace } = await import("./init-Jp_AIMZ7.mjs");
223
+ const { initWorkspace } = await import("./init-BT3STWBv.mjs");
224
224
  const result = await initWorkspace({
225
225
  targetDir: dir,
226
226
  force: opts.force
@@ -359,7 +359,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
359
359
  const { formatToolsTable } = await import("./format-Bq94jSyw.mjs");
360
360
  const { visibleRemoteTools } = await import("./tool-visibility-C0ALejXI.mjs").then((n) => n.i);
361
361
  const { loadConfig } = await import("./config-DA6KRx60.mjs").then((n) => n.t);
362
- const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await import("./client-BD9FLUt2.mjs").then((n) => n.r);
362
+ const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await import("./client-i3WtsKA4.mjs").then((n) => n.r);
363
363
  const config = await loadConfig();
364
364
  const graphMcpEndpoint = resolveGraphMcpEndpoint(config);
365
365
  let tools = opts.refresh ? null : await loadSchema(graphMcpEndpoint);
@@ -429,7 +429,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
429
429
  } catch (err) {
430
430
  const { isMissingUsageStatusToolError, primitiveBackendUsageStatus, usageStatusText } = await import("./usage-status-D2uosC7s.mjs").then((n) => n.n);
431
431
  if (!isMissingUsageStatusToolError(err)) throw err;
432
- const { resolveGraphMcpEndpoint } = await import("./client-BD9FLUt2.mjs").then((n) => n.r);
432
+ const { resolveGraphMcpEndpoint } = await import("./client-i3WtsKA4.mjs").then((n) => n.r);
433
433
  console.log(usageStatusText(primitiveBackendUsageStatus(resolveGraphMcpEndpoint(config))));
434
434
  }
435
435
  return;
@@ -37,6 +37,39 @@ function orderPaymentOptions(accepts, preference, assetSymbols) {
37
37
  return [...accepts].sort((a, b) => rankOf(a) - rankOf(b));
38
38
  }
39
39
  //#endregion
40
+ //#region src/mcp/wallet-proof.ts
41
+ const CIA_WALLET_PROOF_HEADER = "X-CIA-Wallet-Proof";
42
+ function proofMessage(host, unix) {
43
+ return `cia-mcp-permit\n${host}\n${unix}`;
44
+ }
45
+ function proofHostFromUrl(input) {
46
+ if (typeof input === "string") return new URL(input).host;
47
+ if (input instanceof URL) return input.host;
48
+ return new URL(input.url).host;
49
+ }
50
+ async function buildWalletProof(opts) {
51
+ if (!opts.account.signMessage) throw new Error("wallet cannot sign a burnhole proof");
52
+ const unix = Math.floor((opts.now ?? /* @__PURE__ */ new Date()).getTime() / 1e3);
53
+ const signature = await opts.account.signMessage({ message: proofMessage(opts.host, unix) });
54
+ const sigHex = signature.startsWith("0x") ? signature.slice(2) : signature;
55
+ return `v1;${opts.account.address.toLowerCase()};${unix};${sigHex}`;
56
+ }
57
+ function createWalletProofFetch(account, baseFetch, now = () => /* @__PURE__ */ new Date()) {
58
+ return (async (input, init) => {
59
+ if (!account.signMessage) return baseFetch(input, init);
60
+ const headers = new Headers(init?.headers ?? (input instanceof Request ? input.headers : void 0));
61
+ headers.set(CIA_WALLET_PROOF_HEADER, await buildWalletProof({
62
+ account,
63
+ host: proofHostFromUrl(input),
64
+ now: now()
65
+ }));
66
+ return baseFetch(input, {
67
+ ...init,
68
+ headers
69
+ });
70
+ });
71
+ }
72
+ //#endregion
40
73
  //#region src/mcp/client.ts
41
74
  var client_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
42
75
  PAYMENT_NEXT_STEPS: () => PAYMENT_NEXT_STEPS,
@@ -226,7 +259,7 @@ function createPaymentFailureReportingFetch(baseFetch, payerAddress, paymentWall
226
259
  function createMcpFetchClient(privateKey, authToken) {
227
260
  const account = (0, viem_accounts.privateKeyToAccount)(privateKey);
228
261
  const uptoScheme = new _x402_evm_upto_client.UptoEvmScheme(account, EVM_SCHEME_OPTIONS);
229
- const reportingFetch = createPaymentFailureReportingFetch((0, _x402_fetch.wrapFetchWithPaymentFromConfig)(createAssetPreferenceReorderingFetch(fetch, resolvePaymentAssetPreference()), { schemes: [
262
+ const reportingFetch = createPaymentFailureReportingFetch((0, _x402_fetch.wrapFetchWithPaymentFromConfig)(createAssetPreferenceReorderingFetch(createWalletProofFetch(account, fetch), resolvePaymentAssetPreference()), { schemes: [
230
263
  {
231
264
  network: "eip155:8453",
232
265
  client: uptoScheme
@@ -37,6 +37,39 @@ function orderPaymentOptions(accepts, preference, assetSymbols) {
37
37
  return [...accepts].sort((a, b) => rankOf(a) - rankOf(b));
38
38
  }
39
39
  //#endregion
40
+ //#region src/mcp/wallet-proof.ts
41
+ const CIA_WALLET_PROOF_HEADER = "X-CIA-Wallet-Proof";
42
+ function proofMessage(host, unix) {
43
+ return `cia-mcp-permit\n${host}\n${unix}`;
44
+ }
45
+ function proofHostFromUrl(input) {
46
+ if (typeof input === "string") return new URL(input).host;
47
+ if (input instanceof URL) return input.host;
48
+ return new URL(input.url).host;
49
+ }
50
+ async function buildWalletProof(opts) {
51
+ if (!opts.account.signMessage) throw new Error("wallet cannot sign a burnhole proof");
52
+ const unix = Math.floor((opts.now ?? /* @__PURE__ */ new Date()).getTime() / 1e3);
53
+ const signature = await opts.account.signMessage({ message: proofMessage(opts.host, unix) });
54
+ const sigHex = signature.startsWith("0x") ? signature.slice(2) : signature;
55
+ return `v1;${opts.account.address.toLowerCase()};${unix};${sigHex}`;
56
+ }
57
+ function createWalletProofFetch(account, baseFetch, now = () => /* @__PURE__ */ new Date()) {
58
+ return (async (input, init) => {
59
+ if (!account.signMessage) return baseFetch(input, init);
60
+ const headers = new Headers(init?.headers ?? (input instanceof Request ? input.headers : void 0));
61
+ headers.set(CIA_WALLET_PROOF_HEADER, await buildWalletProof({
62
+ account,
63
+ host: proofHostFromUrl(input),
64
+ now: now()
65
+ }));
66
+ return baseFetch(input, {
67
+ ...init,
68
+ headers
69
+ });
70
+ });
71
+ }
72
+ //#endregion
40
73
  //#region src/mcp/client.ts
41
74
  var client_exports = /* @__PURE__ */ __exportAll({
42
75
  PAYMENT_NEXT_STEPS: () => PAYMENT_NEXT_STEPS,
@@ -226,7 +259,7 @@ function createPaymentFailureReportingFetch(baseFetch, payerAddress, paymentWall
226
259
  function createMcpFetchClient(privateKey, authToken) {
227
260
  const account = privateKeyToAccount(privateKey);
228
261
  const uptoScheme = new UptoEvmScheme(account, EVM_SCHEME_OPTIONS);
229
- const reportingFetch = createPaymentFailureReportingFetch(wrapFetchWithPaymentFromConfig(createAssetPreferenceReorderingFetch(fetch, resolvePaymentAssetPreference()), { schemes: [
262
+ const reportingFetch = createPaymentFailureReportingFetch(wrapFetchWithPaymentFromConfig(createAssetPreferenceReorderingFetch(createWalletProofFetch(account, fetch), resolvePaymentAssetPreference()), { schemes: [
230
263
  {
231
264
  network: "eip155:8453",
232
265
  client: uptoScheme
@@ -279,4 +312,4 @@ async function createConfiguredGraphMcpFetch(config) {
279
312
  //#endregion
280
313
  export { resolveGraphMcpEndpoint as a, createMcpFetchClient as i, applyMcpAuthHeaders as n, client_exports as r, PaymentRequiredError as t };
281
314
 
282
- //# sourceMappingURL=client-BD9FLUt2.mjs.map
315
+ //# sourceMappingURL=client-i3WtsKA4.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-i3WtsKA4.mjs","names":[],"sources":["../src/mcp/payment-asset-preference.ts","../src/mcp/wallet-proof.ts","../src/mcp/client.ts"],"sourcesContent":["/**\n * Payment-asset preference ordering for 402 `accepts` offers.\n *\n * Chain Insights Graph can quote a paid MCP call in more than one ERC-20\n * asset across networks (USDC on Base, USDG/CHOICE on Robinhood Chain). The\n * x402 client's default selector always pays with the first `accepts` entry\n * it can pay with, so re-ordering `accepts` by operator preference before\n * the payment scheme picks lets an operator route payments to a preferred\n * asset without any server-side change.\n */\n\nexport interface PaymentOptionLike {\n network: string // CAIP-2, e.g. \"eip155:8453\"\n asset: string // ERC-20 token contract address\n amount: string // base units\n extra?: Record<string, unknown>\n}\n\n/**\n * Known payment asset symbols by lowercase contract address. Extend this map\n * as new payment assets go live; an address not listed here can still be\n * targeted directly by address in CHAIN_INSIGHTS_PAYMENT_ASSET_PREFERENCE.\n */\nexport const KNOWN_PAYMENT_ASSET_SYMBOLS: Record<string, string> = {\n '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913': 'USDC', // Base\n '0x5fc5360d0400a0fd4f2af552add042d716f1d168': 'USDG', // Robinhood Chain\n '0x6e30a5f8fc61cd4e8550d2dd3cddea2a0196dc69': 'CHOICE', // Robinhood Chain (test token)\n}\n\n/**\n * Orders 402 `accepts` by the operator preference list (env\n * CHAIN_INSIGHTS_PAYMENT_ASSET_PREFERENCE, comma-separated symbols or\n * addresses, e.g. \"CHOICE,USDG,USDC\"). Unlisted assets keep server order\n * after listed ones. Empty preference -> server order (today's behavior).\n *\n * Pure: does not mutate `accepts`. Matching is case-insensitive for both\n * symbols and addresses, and the sort is stable so ties (unlisted assets,\n * or repeated preference entries) preserve server order.\n */\nexport function orderPaymentOptions(\n accepts: PaymentOptionLike[],\n preference: string,\n assetSymbols: Record<string, string>,\n): PaymentOptionLike[] {\n const preferenceList = preference\n .split(',')\n .map((entry) => entry.trim().toLowerCase())\n .filter(Boolean)\n\n if (preferenceList.length === 0) return accepts\n\n const rankOf = (option: PaymentOptionLike): number => {\n const addressLower = option.asset.toLowerCase()\n const symbolLower = assetSymbols[addressLower]?.toLowerCase()\n const rank = preferenceList.findIndex((entry) => entry === symbolLower || entry === addressLower)\n return rank === -1 ? preferenceList.length : rank\n }\n\n return [...accepts].sort((a, b) => rankOf(a) - rankOf(b))\n}\n","import type { Account } from 'viem'\n\ntype FetchLike = typeof fetch\ntype FetchInput = Parameters<FetchLike>[0]\ntype FetchInit = Parameters<FetchLike>[1]\n\nexport const CIA_WALLET_PROOF_HEADER = 'X-CIA-Wallet-Proof'\n\nexport function proofMessage(host: string, unix: number): string {\n return `cia-mcp-permit\\n${host}\\n${unix}`\n}\n\nexport function proofHostFromUrl(input: FetchInput): string {\n if (typeof input === 'string') {\n return new URL(input).host\n }\n if (input instanceof URL) {\n return input.host\n }\n return new URL(input.url).host\n}\n\nexport async function buildWalletProof(opts: {\n account: Pick<Account, 'address' | 'signMessage'>\n host: string\n now?: Date\n}): Promise<string> {\n if (!opts.account.signMessage) {\n throw new Error('wallet cannot sign a burnhole proof')\n }\n const unix = Math.floor((opts.now ?? new Date()).getTime() / 1000)\n const signature = await opts.account.signMessage({\n message: proofMessage(opts.host, unix),\n })\n const sigHex = signature.startsWith('0x') ? signature.slice(2) : signature\n return `v1;${opts.account.address.toLowerCase()};${unix};${sigHex}`\n}\n\nexport function createWalletProofFetch(\n account: Pick<Account, 'address' | 'signMessage'>,\n baseFetch: FetchLike,\n now: () => Date = () => new Date(),\n): FetchLike {\n return (async (input: FetchInput, init?: FetchInit) => {\n if (!account.signMessage) {\n return baseFetch(input, init)\n }\n const headers = new Headers(init?.headers ?? (input instanceof Request ? input.headers : undefined))\n headers.set(\n CIA_WALLET_PROOF_HEADER,\n await buildWalletProof({ account, host: proofHostFromUrl(input), now: now() }),\n )\n return baseFetch(input, { ...init, headers })\n }) as FetchLike\n}\n","import { wrapFetchWithPaymentFromConfig } from '@x402/fetch'\nimport { ExactEvmScheme } from '@x402/evm'\nimport { UptoEvmScheme, type UptoEvmSchemeConfigByChainId } from '@x402/evm/upto/client'\nimport { privateKeyToAccount } from 'viem/accounts'\nimport type { InvestigatorConfig } from '../config/schema.js'\nimport { prepareWalletForPaidCalls, resolveMaxAutoApprovalUnits, PERMIT2_ADDRESS, USDC_ADDRESS } from '../wallet/tools.js'\nimport { orderPaymentOptions, KNOWN_PAYMENT_ASSET_SYMBOLS, type PaymentOptionLike } from './payment-asset-preference.js'\nimport { createWalletProofFetch } from './wallet-proof.js'\n\ntype FetchLike = typeof fetch\ntype FetchInput = Parameters<FetchLike>[0]\ntype FetchInit = Parameters<FetchLike>[1]\n\n// Robinhood Chain — second EVM network accepted for x402 Permit2 payments\n// alongside Base Mainnet. The x402 SDK builds its own bare RPC client per\n// chain ID from this config (no viem chain-registry entry is needed: it\n// never imports `viem/chains`, it just does `createPublicClient({transport:\n// http(rpcUrl)})` keyed by CAIP-2 chain ID).\nexport const ROBINHOOD_CHAIN_ID = 4663\nexport const ROBINHOOD_NETWORK = 'eip155:4663'\nexport const ROBINHOOD_RPC_URL = 'https://rpc.mainnet.chain.robinhood.com'\n\nconst EVM_SCHEME_OPTIONS: UptoEvmSchemeConfigByChainId = {\n [ROBINHOOD_CHAIN_ID]: { rpcUrl: ROBINHOOD_RPC_URL },\n}\n\n/**\n * Reads the operator's payment-asset preference order (env\n * CHAIN_INSIGHTS_PAYMENT_ASSET_PREFERENCE, comma-separated symbols or\n * addresses). Empty/unset keeps server order.\n */\nexport function resolvePaymentAssetPreference(env: NodeJS.ProcessEnv = process.env): string {\n return env['CHAIN_INSIGHTS_PAYMENT_ASSET_PREFERENCE']?.trim() ?? ''\n}\n\n/**\n * Wraps `fetch` so that a 402 response's `accepts` offers are re-ordered by\n * the operator's payment-asset preference before the x402 client's default\n * selector (which always picks `accepts[0]`) runs. Must wrap the raw\n * transport `fetch` passed into `wrapFetchWithPaymentFromConfig`, not the\n * result of it, since the x402 client parses `accepts` from the first 402\n * response it sees.\n */\nfunction createAssetPreferenceReorderingFetch(baseFetch: FetchLike, preference: string): FetchLike {\n if (!preference) return baseFetch\n return (async (input: FetchInput, init?: FetchInit) => {\n const response = await baseFetch(input, init)\n if (response.status !== 402) return response\n const encoded = response.headers.get('payment-required')\n if (!encoded) return response\n\n let parsed: { accepts?: PaymentOptionLike[] } & Record<string, unknown>\n try {\n parsed = JSON.parse(Buffer.from(encoded, 'base64').toString('utf8'))\n } catch {\n return response\n }\n if (!Array.isArray(parsed.accepts) || parsed.accepts.length === 0) return response\n\n const reordered = orderPaymentOptions(parsed.accepts, preference, KNOWN_PAYMENT_ASSET_SYMBOLS)\n const reencoded = Buffer.from(JSON.stringify({ ...parsed, accepts: reordered })).toString('base64')\n const headers = new Headers(response.headers)\n headers.set('payment-required', reencoded)\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n })\n }) as FetchLike\n}\n\nexport class PaymentRequiredError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'PaymentRequiredError'\n }\n}\n\nexport function applyMcpAuthHeaders(headers: Headers, authToken: string): Headers {\n headers.set('X-MCP-Debug-Token', authToken)\n headers.set('X-MCP-Test-Key', authToken)\n headers.set('X-Chain-Insights-Test-Key', authToken)\n headers.set('Authorization', `Bearer ${authToken}`)\n return headers\n}\n\nfunction createHeaderFetch(authToken: string, baseFetch: FetchLike): FetchLike {\n return (async (input: FetchInput, init?: FetchInit) => {\n const requestHeaders = input instanceof Request ? input.headers : undefined\n const headers = new Headers(init?.headers ?? requestHeaders)\n applyMcpAuthHeaders(headers, authToken)\n\n return baseFetch(input, {\n ...init,\n headers,\n })\n }) as FetchLike\n}\n\nexport const PAYMENT_NEXT_STEPS =\n 'Next steps: run `chain-insights wallet ready` to check funding and finish one-time payment setup, ' +\n 'run `chain-insights wallet topup` if it says the wallet needs USDC, ' +\n 'or `chain-insights access-key set <key>` if you have been given test access.'\n\ninterface PaymentRequirementDetails {\n reason: string\n scheme?: string\n network?: string\n amount?: string\n amountUnits?: bigint\n payTo?: string\n asset?: string\n}\n\nfunction paymentRequirementFromResponse(response: Response): PaymentRequirementDetails | null {\n const encoded = response.headers.get('payment-required')\n if (!encoded) return null\n\n try {\n const decoded = Buffer.from(encoded, 'base64').toString('utf8')\n const parsed = JSON.parse(decoded) as {\n error?: unknown\n accepts?: Array<{ scheme?: unknown; network?: unknown; amount?: unknown; payTo?: unknown; asset?: unknown }>\n }\n const reason = typeof parsed.error === 'string' && parsed.error.trim() ? parsed.error.trim() : 'payment_required'\n const firstRequirement = Array.isArray(parsed.accepts) ? parsed.accepts[0] : undefined\n const amount = typeof firstRequirement?.amount === 'string' ? firstRequirement.amount.trim() : undefined\n return {\n reason,\n scheme: typeof firstRequirement?.scheme === 'string' ? firstRequirement.scheme : undefined,\n network: typeof firstRequirement?.network === 'string' ? firstRequirement.network : undefined,\n amount,\n amountUnits: amount && /^\\d+$/.test(amount) ? BigInt(amount) : undefined,\n payTo: typeof firstRequirement?.payTo === 'string' ? firstRequirement.payTo.trim() : undefined,\n asset: typeof firstRequirement?.asset === 'string' ? firstRequirement.asset.trim() : undefined,\n }\n } catch {\n return null\n }\n}\n\n/**\n * True only for the one combination this client can auto-approve today:\n * USDC on Base, via the existing Base-only `wallet/tools.ts` allowance flow.\n * A requirement with no `asset` at all predates multi-asset 402 offers and\n * is treated as that same legacy USDC-on-Base case.\n */\nfunction isAutoApprovableBaseUsdc(requirement: PaymentRequirementDetails): boolean {\n if (requirement.network !== 'eip155:8453') return false\n if (!requirement.asset) return true\n return requirement.asset.toLowerCase() === USDC_ADDRESS.toLowerCase()\n}\n\n/**\n * Clear, actionable error for the case the auto-approval flow does not cover:\n * a Permit2 allowance is missing for a non-Base-USDC asset (e.g. USDG/CHOICE\n * on Robinhood Chain) and the server did not offer a gas-sponsored approval\n * extension. Names the token, the canonical Permit2 address, and the exact\n * approval call so the operator can run it manually.\n */\nfunction describePermit2ApprovalNeededError(requirement: PaymentRequirementDetails): string {\n const token = requirement.asset ?? 'the payment token'\n const networkSuffix = requirement.network ? ` on ${requirement.network}` : ''\n return (\n `Payment requires a one-time Permit2 approval for token ${token}${networkSuffix} before paid calls can settle, ` +\n 'and gas-sponsored approval is not available for this asset. ' +\n `Approve the canonical Permit2 contract ${PERMIT2_ADDRESS} to spend ${token} by calling ` +\n `approve(${PERMIT2_ADDRESS}, <amount>) on the token contract, then retry the call.`\n )\n}\n\nfunction describePaymentRequiredResponse(response: Response, payerAddress?: string): string {\n const requirement = paymentRequirementFromResponse(response)\n if (!requirement) return `Payment required — this tool costs USDC on Base via x402 micropayments. ${PAYMENT_NEXT_STEPS}`\n\n try {\n const { reason, payTo } = requirement\n if (payerAddress && payTo && payerAddress.toLowerCase() === payTo.toLowerCase()) {\n return 'Local payment wallet matches the MCP payTo address. Configure a separate payer wallet with USDC on Base; do not use the service recipient wallet as the client payment wallet.'\n }\n const details = [\n requirement.scheme ? `scheme=${requirement.scheme}` : undefined,\n requirement.network ? `network=${requirement.network}` : undefined,\n requirement.amount ? `amount=${requirement.amount}` : undefined,\n ].filter(Boolean).join(' ')\n const message = details ? `x402 payment failed: ${reason} (${details})` : `x402 payment failed: ${reason}`\n if (reason.includes('allowance_required')) {\n return `${message}. The payment wallet needs one-time setup before paid MCP calls can settle. Run \\`chain-insights wallet ready\\`; Base ETH is used for the setup gas.`\n }\n if (reason === 'payment_required') {\n return `${message}. ${PAYMENT_NEXT_STEPS}`\n }\n return `${message}. ${PAYMENT_NEXT_STEPS}`\n } catch {\n return `Payment required — this tool costs USDC on Base via x402 micropayments. ${PAYMENT_NEXT_STEPS}`\n }\n}\n\nfunction createPaymentFailureReportingFetch(\n baseFetch: FetchLike,\n payerAddress?: string,\n paymentWallet?: { address: `0x${string}`; privateKey: `0x${string}` },\n): FetchLike {\n const reportingFetch = (async (input: FetchInput, init?: FetchInit) => {\n const response = await baseFetch(input, init)\n if (response.status !== 402) return response\n const requirement = paymentRequirementFromResponse(response)\n if (paymentWallet && requirement?.reason.includes('allowance_required')) {\n if (!isAutoApprovableBaseUsdc(requirement)) {\n throw new PaymentRequiredError(describePermit2ApprovalNeededError(requirement))\n }\n try {\n await prepareWalletForPaidCalls({\n account: paymentWallet,\n // The endpoint dictates requirement.amountUnits; cap it so a hostile\n // endpoint cannot drive an unbounded Permit2 approval / wallet drain.\n maxApprovalUnits: resolveMaxAutoApprovalUnits(),\n ...(requirement.amountUnits === undefined ? {} : { minimumApprovalUnits: requirement.amountUnits }),\n })\n } catch (err) {\n throw new PaymentRequiredError(\n 'Payment setup is not ready yet. Run `chain-insights wallet ready` and try again. ' +\n `${(err as Error).message}`,\n )\n }\n const retryResponse = await baseFetch(input, init)\n if (retryResponse.status !== 402) return retryResponse\n throw new PaymentRequiredError(describePaymentRequiredResponse(retryResponse, payerAddress))\n }\n throw new PaymentRequiredError(describePaymentRequiredResponse(response, payerAddress))\n }) as FetchLike\n return Object.assign(reportingFetch, baseFetch)\n}\n\n/**\n * Creates an x402-payment-wrapped fetch function for the Chain Insights MCP.\n * Payments are made in USDC on Base Mainnet (eip155:8453) or, when the\n * server offers it and the operator prefers it, a Permit2 asset on\n * Robinhood Chain (eip155:4663) — see ROBINHOOD_NETWORK.\n *\n * The factory is pure — no side effects, no state, no caching.\n * If called with an invalid private key format, viem throws — the error propagates.\n *\n * @param privateKey - 0x-prefixed EVM private key (decrypted from wallet.json)\n * @returns A fetch-compatible function that auto-handles HTTP 402 payment challenges\n */\nexport function createMcpFetchClient(privateKey: `0x${string}`, authToken?: string) {\n const account = privateKeyToAccount(privateKey)\n // Shared across both networks: EVM_SCHEME_OPTIONS is keyed by chain ID, so\n // it only supplies an RPC URL for Robinhood Chain (4663) and leaves Base\n // (8453) exactly as before (no RPC configured — gas-sponsored approval\n // stays unavailable there too, unchanged from prior behavior).\n const uptoScheme = new UptoEvmScheme(account, EVM_SCHEME_OPTIONS)\n const paymentFetch = wrapFetchWithPaymentFromConfig(\n createAssetPreferenceReorderingFetch(createWalletProofFetch(account, fetch), resolvePaymentAssetPreference()),\n {\n schemes: [\n {\n network: 'eip155:8453', // Base Mainnet — dynamic MCP pricing uses the x402 upto scheme\n client: uptoScheme,\n },\n {\n network: 'eip155:8453', // Base Mainnet — only supported chain in v1\n client: new ExactEvmScheme(account),\n },\n {\n network: ROBINHOOD_NETWORK, // Robinhood Chain — Permit2-only (upto scheme), same client instance\n client: uptoScheme,\n },\n ],\n },\n )\n const reportingFetch = createPaymentFailureReportingFetch(\n paymentFetch,\n account.address,\n { address: account.address, privateKey },\n )\n return authToken ? createHeaderFetch(authToken, reportingFetch) : reportingFetch\n}\n\n/**\n * Creates a bearer/debug-token fetch for local Chain Insights Graph testing.\n *\n * Chain Insights Graph deployments accept test access through the public debug header,\n * staging test-key headers, or Authorization: Bearer depending on the route.\n * Sending all supported auth headers lets one config value work across hosted\n * MCP calls, metadata reads, and private M2M endpoints.\n *\n * Wraps with 402 interception so that if the server still requires payment\n * (e.g. token not accepted for paid tools), the user sees actionable guidance\n * instead of a generic transport error.\n */\nexport function createMcpAuthFetchClient(authToken: string, baseFetch: FetchLike = fetch): FetchLike {\n const headerFetch = createHeaderFetch(authToken, baseFetch)\n return createPaymentFailureReportingFetch(headerFetch)\n}\n\nexport function resolveGraphMcpEndpoint(config: Pick<InvestigatorConfig, 'graphMcpEndpoint'>): string {\n return config.graphMcpEndpoint.trim()\n}\n\nasync function createConfiguredGraphPaidOrFreeFetch(): Promise<FetchLike> {\n const { isWalletConfigured, decryptKey } = await import('../wallet/index.js')\n if (!(await isWalletConfigured())) {\n return createPaymentFailureReportingFetch(fetch)\n }\n\n const privateKey = await decryptKey()\n return createMcpFetchClient(privateKey as `0x${string}`)\n}\n\nexport async function createConfiguredGraphMcpFetch(\n config: Pick<InvestigatorConfig, 'graphMcpAuthToken' | 'graphMcpMode'>,\n): Promise<FetchLike> {\n if (config.graphMcpMode === 'debug') {\n const authToken = config.graphMcpAuthToken?.trim()\n if (!authToken) {\n throw new Error('Chain Insights Graph debug mode requires graphMcpAuthToken. Run `cia access-key set <key>` or `cia debug on --token <token>`.')\n }\n return createMcpAuthFetchClient(authToken)\n }\n\n return createConfiguredGraphPaidOrFreeFetch()\n}\n"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -5,7 +5,7 @@ const require_server = require("./server-ta1oyJ2a.cjs");
5
5
  const require_wallet = require("./wallet-C2yVjcSY.cjs");
6
6
  const require_tools = require("./tools-BPfUpCUR.cjs");
7
7
  const require_topup_server = require("./topup-server-VGl8-Fz5.cjs");
8
- const require_client = require("./client-DLqndaSv.cjs");
8
+ const require_client = require("./client-Bjxo7AEa.cjs");
9
9
  const require_merge = require("./merge-B_5kxbGv.cjs");
10
10
  const require_viz = require("./viz-HSwLcKr6.cjs");
11
11
  exports.buildTopupInfo = require_tools.buildTopupInfo;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/config/schema.ts","../src/config/index.ts","../src/server/app.ts","../src/server/index.ts","../src/wallet/index.ts","../src/wallet/tools.ts","../src/wallet/mcp-proxy/topup-server.ts","../src/wallet/topup-server.ts","../src/mcp/client.ts","../src/federation/merge.ts","../src/viz/graph-model.ts","../src/viz/index.ts"],"mappings":";;;;cA0Da,cAAY,EAAA;;;;;;;;;;;;;GAUvB,EAAA,KAAA;KAEU,qBAAqB,EAAE,aAAa;;;iBCnB1B,cAAc,QAAQ;iBAMtB,WAAW,SAAS,QAAQ,sBAAsB;iBAclD,oBAAoB;;;iBCkC1B,aAAa;;;iBCtGb,YAAY;;;iBC0BZ,0BAA0B,gBAAgB;iBAO1C,4BAA4B,qBAAqB;;;;;;;;iBAW3C,WAAW,qBAAqB;UA2BrC;;EAEf;;;;;;;;iBAuCoB,oBACpB,oBACA,UAAS,6BACR,QAAQ;;;;;;;iBA2BW,cAAc;;;;;iBA2Cd,sBAAsB;;;cCvL/B;cACA;UAgDI;EACf,SAAS;EACT,YAAY;;UAGG;EACf;EACA;EACA,iBAAiB;EACjB;EACA,uBAAuB;EACvB;;UAoDe;EACf,SAAS;EACT;EACA;EACA,iBAAiB;EACjB;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;IACE,QAAQ;;;iBAIU,oBAAoB,QAAQ;iBAa5B,eACpB,SAAS,kBACT,8BACC;iBAsBmB,cACpB,SAAS,kBACT,8BACC;iBAuPa,oBAAoB,iBAAiB,qBAAqB;iBAUpD,uBAAuB,UAAU,uBAAuB,QAAQ;iBAyBtE,0BAA0B,QAAQ;iBAK5B,qBAAqB,UAAU,uBAAuB;iBAI5D,eAAe,iBAAiB,oBAAoB;;;iBC9VpD,qBAAqB,4BAA4B;;;iBClBjD;iBAcM,iBAAiB,SAAS,gCAAgC;;;;;;;;;;;;;;;iBCkIhE,qBAAqB,2BAA2B,4BAAkB;;;;;;;;;;;;;;KCzOtE,WAAW;EAA4B;;UAElC;EACf;IAAY;IAAa;;EACzB;EACA,WAAW,MAAM;;;;;;;;EAQjB;;;;EAIA;;UAGe;EACf,MAAM,MAAM;;;;;EAKZ,UAAU,eAAe,MAAM;EAC/B;;iBAwJc,eAAe,MAAM,YAAY,OAAM,eAAoB;;;cCtL9D,WAAS,EAAA;;;;;;;;;;;;;;;;;;;;;;;;GAUpB,EAAA,KAAA;KACU,YAAY,EAAE,aAAa;cAE1B,WAAS,EAAA;;;;;;;;GAUpB,EAAA,KAAA;KACU,YAAY,EAAE,aAAa;cAE1B,WAAS,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAUpB,EAAA,KAAA;KACU,YAAY,EAAE,aAAa;;;iBC3BjB,sBAAsB;EAC1C;EACA;IACE;EAAU;EAAe"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/config/schema.ts","../src/config/index.ts","../src/server/app.ts","../src/server/index.ts","../src/wallet/index.ts","../src/wallet/tools.ts","../src/wallet/mcp-proxy/topup-server.ts","../src/wallet/topup-server.ts","../src/mcp/client.ts","../src/federation/merge.ts","../src/viz/graph-model.ts","../src/viz/index.ts"],"mappings":";;;;cA0Da,cAAY,EAAA;;;;;;;;;;;;;GAUvB,EAAA,KAAA;KAEU,qBAAqB,EAAE,aAAa;;;iBCnB1B,cAAc,QAAQ;iBAMtB,WAAW,SAAS,QAAQ,sBAAsB;iBAclD,oBAAoB;;;iBCkC1B,aAAa;;;iBCtGb,YAAY;;;iBC0BZ,0BAA0B,gBAAgB;iBAO1C,4BAA4B,qBAAqB;;;;;;;;iBAW3C,WAAW,qBAAqB;UA2BrC;;EAEf;;;;;;;;iBAuCoB,oBACpB,oBACA,UAAS,6BACR,QAAQ;;;;;;;iBA2BW,cAAc;;;;;iBA2Cd,sBAAsB;;;cCvL/B;cACA;UAgDI;EACf,SAAS;EACT,YAAY;;UAGG;EACf;EACA;EACA,iBAAiB;EACjB;EACA,uBAAuB;EACvB;;UAoDe;EACf,SAAS;EACT;EACA;EACA,iBAAiB;EACjB;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;IACE,QAAQ;;;iBAIU,oBAAoB,QAAQ;iBAa5B,eACpB,SAAS,kBACT,8BACC;iBAsBmB,cACpB,SAAS,kBACT,8BACC;iBAuPa,oBAAoB,iBAAiB,qBAAqB;iBAUpD,uBAAuB,UAAU,uBAAuB,QAAQ;iBAyBtE,0BAA0B,QAAQ;iBAK5B,qBAAqB,UAAU,uBAAuB;iBAI5D,eAAe,iBAAiB,oBAAoB;;;iBC9VpD,qBAAqB,4BAA4B;;;iBClBjD;iBAcM,iBAAiB,SAAS,gCAAgC;;;;;;;;;;;;;;;iBCmIhE,qBAAqB,2BAA2B,4BAAkB;;;;;;;;;;;;;;KC1OtE,WAAW;EAA4B;;UAElC;EACf;IAAY;IAAa;;EACzB;EACA,WAAW,MAAM;;;;;;;;EAQjB;;;;EAIA;;UAGe;EACf,MAAM,MAAM;;;;;EAKZ,UAAU,eAAe,MAAM;EAC/B;;iBAwJc,eAAe,MAAM,YAAY,OAAM,eAAoB;;;cCtL9D,WAAS,EAAA;;;;;;;;;;;;;;;;;;;;;;;;GAUpB,EAAA,KAAA;KACU,YAAY,EAAE,aAAa;cAE1B,WAAS,EAAA;;;;;;;;GAUpB,EAAA,KAAA;KACU,YAAY,EAAE,aAAa;cAE1B,WAAS,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAUpB,EAAA,KAAA;KACU,YAAY,EAAE,aAAa;;;iBC3BjB,sBAAsB;EAC1C;EACA;IACE;EAAU;EAAe"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/config/schema.ts","../src/config/index.ts","../src/server/app.ts","../src/server/index.ts","../src/wallet/index.ts","../src/wallet/tools.ts","../src/wallet/mcp-proxy/topup-server.ts","../src/wallet/topup-server.ts","../src/mcp/client.ts","../src/federation/merge.ts","../src/viz/graph-model.ts","../src/viz/index.ts"],"mappings":";;;;cA0Da,cAAY,EAAA;;;;;;;;;;;;;GAUvB,EAAA,KAAA;KAEU,qBAAqB,EAAE,aAAa;;;iBCnB1B,cAAc,QAAQ;iBAMtB,WAAW,SAAS,QAAQ,sBAAsB;iBAclD,oBAAoB;;;iBCkC1B,aAAa;;;iBCtGb,YAAY;;;iBC0BZ,0BAA0B,gBAAgB;iBAO1C,4BAA4B,qBAAqB;;;;;;;;iBAW3C,WAAW,qBAAqB;UA2BrC;;EAEf;;;;;;;;iBAuCoB,oBACpB,oBACA,UAAS,6BACR,QAAQ;;;;;;;iBA2BW,cAAc;;;;;iBA2Cd,sBAAsB;;;cCvL/B;cACA;UAgDI;EACf,SAAS;EACT,YAAY;;UAGG;EACf;EACA;EACA,iBAAiB;EACjB;EACA,uBAAuB;EACvB;;UAoDe;EACf,SAAS;EACT;EACA;EACA,iBAAiB;EACjB;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;IACE,QAAQ;;;iBAIU,oBAAoB,QAAQ;iBAa5B,eACpB,SAAS,kBACT,8BACC;iBAsBmB,cACpB,SAAS,kBACT,8BACC;iBAuPa,oBAAoB,iBAAiB,qBAAqB;iBAUpD,uBAAuB,UAAU,uBAAuB,QAAQ;iBAyBtE,0BAA0B,QAAQ;iBAK5B,qBAAqB,UAAU,uBAAuB;iBAI5D,eAAe,iBAAiB,oBAAoB;;;iBC9VpD,qBAAqB,4BAA4B;;;iBClBjD;iBAcM,iBAAiB,SAAS,gCAAgC;;;;;;;;;;;;;;;iBCkIhE,qBAAqB,2BAA2B,4BAAkB;;;;;;;;;;;;;;KCzOtE,WAAW;EAA4B;;UAElC;EACf;IAAY;IAAa;;EACzB;EACA,WAAW,MAAM;;;;;;;;EAQjB;;;;EAIA;;UAGe;EACf,MAAM,MAAM;;;;;EAKZ,UAAU,eAAe,MAAM;EAC/B;;iBAwJc,eAAe,MAAM,YAAY,OAAM,eAAoB;;;cCtL9D,WAAS,EAAA;;;;;;;;;;;;;;;;;;;;;;;;GAUpB,EAAA,KAAA;KACU,YAAY,EAAE,aAAa;cAE1B,WAAS,EAAA;;;;;;;;GAUpB,EAAA,KAAA;KACU,YAAY,EAAE,aAAa;cAE1B,WAAS,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAUpB,EAAA,KAAA;KACU,YAAY,EAAE,aAAa;;;iBC3BjB,sBAAsB;EAC1C;EACA;IACE;EAAU;EAAe"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/config/schema.ts","../src/config/index.ts","../src/server/app.ts","../src/server/index.ts","../src/wallet/index.ts","../src/wallet/tools.ts","../src/wallet/mcp-proxy/topup-server.ts","../src/wallet/topup-server.ts","../src/mcp/client.ts","../src/federation/merge.ts","../src/viz/graph-model.ts","../src/viz/index.ts"],"mappings":";;;;cA0Da,cAAY,EAAA;;;;;;;;;;;;;GAUvB,EAAA,KAAA;KAEU,qBAAqB,EAAE,aAAa;;;iBCnB1B,cAAc,QAAQ;iBAMtB,WAAW,SAAS,QAAQ,sBAAsB;iBAclD,oBAAoB;;;iBCkC1B,aAAa;;;iBCtGb,YAAY;;;iBC0BZ,0BAA0B,gBAAgB;iBAO1C,4BAA4B,qBAAqB;;;;;;;;iBAW3C,WAAW,qBAAqB;UA2BrC;;EAEf;;;;;;;;iBAuCoB,oBACpB,oBACA,UAAS,6BACR,QAAQ;;;;;;;iBA2BW,cAAc;;;;;iBA2Cd,sBAAsB;;;cCvL/B;cACA;UAgDI;EACf,SAAS;EACT,YAAY;;UAGG;EACf;EACA;EACA,iBAAiB;EACjB;EACA,uBAAuB;EACvB;;UAoDe;EACf,SAAS;EACT;EACA;EACA,iBAAiB;EACjB;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;IACE,QAAQ;;;iBAIU,oBAAoB,QAAQ;iBAa5B,eACpB,SAAS,kBACT,8BACC;iBAsBmB,cACpB,SAAS,kBACT,8BACC;iBAuPa,oBAAoB,iBAAiB,qBAAqB;iBAUpD,uBAAuB,UAAU,uBAAuB,QAAQ;iBAyBtE,0BAA0B,QAAQ;iBAK5B,qBAAqB,UAAU,uBAAuB;iBAI5D,eAAe,iBAAiB,oBAAoB;;;iBC9VpD,qBAAqB,4BAA4B;;;iBClBjD;iBAcM,iBAAiB,SAAS,gCAAgC;;;;;;;;;;;;;;;iBCmIhE,qBAAqB,2BAA2B,4BAAkB;;;;;;;;;;;;;;KC1OtE,WAAW;EAA4B;;UAElC;EACf;IAAY;IAAa;;EACzB;EACA,WAAW,MAAM;;;;;;;;EAQjB;;;;EAIA;;UAGe;EACf,MAAM,MAAM;;;;;EAKZ,UAAU,eAAe,MAAM;EAC/B;;iBAwJc,eAAe,MAAM,YAAY,OAAM,eAAoB;;;cCtL9D,WAAS,EAAA;;;;;;;;;;;;;;;;;;;;;;;;GAUpB,EAAA,KAAA;KACU,YAAY,EAAE,aAAa;cAE1B,WAAS,EAAA;;;;;;;;GAUpB,EAAA,KAAA;KACU,YAAY,EAAE,aAAa;cAE1B,WAAS,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAUpB,EAAA,KAAA;KACU,YAAY,EAAE,aAAa;;;iBC3BjB,sBAAsB;EAC1C;EACA;IACE;EAAU;EAAe"}
package/dist/index.mjs CHANGED
@@ -4,7 +4,7 @@ import { n as startServer } from "./server-BXj6BRI1.mjs";
4
4
  import { a as setWalletPrivateKey, i as normalizeWalletPrivateKey, n as encryptKey, o as walletAddressFromPrivateKey, r as isWalletConfigured, t as decryptKey } from "./wallet-BrTTnf7w.mjs";
5
5
  import { a as formatWalletBalanceResult, c as getWalletAccount, i as formatWalletBalance, l as getWalletBalanceResult, o as getBalanceEth, r as buildTopupInfo, s as getBalanceUsdc, u as getWalletBalanceText } from "./tools-CWwX4yth.mjs";
6
6
  import { i as generateArtifactHtml, n as startTopupServer, t as getTopupUrl } from "./topup-server-D2X7My7i.mjs";
7
- import { i as createMcpFetchClient } from "./client-BD9FLUt2.mjs";
7
+ import { i as createMcpFetchClient } from "./client-i3WtsKA4.mjs";
8
8
  import { t as mergeShardRows } from "./merge-CJRZpuZ4.mjs";
9
9
  import { t as generateVisualization } from "./viz-Cq1jSWSH.mjs";
10
10
  export { buildTopupInfo, createApp, createMcpFetchClient, decryptKey, encryptKey, formatWalletBalance, formatWalletBalanceResult, generateArtifactHtml, generateVisualization, getBalanceEth, getBalanceUsdc, getTopupUrl, getWalletAccount, getWalletBalanceResult, getWalletBalanceText, isWalletConfigured, loadConfig, mergeShardRows, normalizeWalletPrivateKey, resetConfigCache, saveConfig, setWalletPrivateKey, startServer, startTopupServer, walletAddressFromPrivateKey };
@@ -160,17 +160,17 @@ property names for the active network.
160
160
 
161
161
  The address-grain graph schema:
162
162
 
163
- - All Chain Insights investigation runs on ONE public network: always pass
164
- \`network=robinhood\` — one EVM H160 (\`0x...\`) address space, no SS58.
165
- Every topology node is \`(:Address {address, network})\`, keyed by
166
- the raw chain-native \`address\`; there is no SS58/H160 split and no
167
- second query network. There is no separate identity key and no
168
- member-address satellite: the address IS the graph node.
163
+ - Call \`meta_network_capabilities\` first. Pass \`network=\` exactly as
164
+ GraphRAG advertised it. CIA does not pick a default network.
165
+ Address format follows that network. Every topology node is
166
+ \`(:Address {address, network})\`, keyed by the raw chain-native
167
+ \`address\`. There is no separate identity key and no member-address
168
+ satellite: the address IS the graph node.
169
169
  - \`(:Address)-[:LINKED]-(:Address)\` is an **undirected** ownership-overlay
170
170
  edge (\`basis\` \`derived\`/\`associated\`, plus \`confidence\`,
171
171
  \`source_event\`, \`declared_owner\`) asserting the two addresses are
172
172
  controlled by the same actor. \`LINKED\` is the ownership edge within the
173
- single \`network=robinhood\` space — a same-network query traces
173
+ advertised network — a same-network query traces
174
174
  (\`LINKED\` or \`FLOWS_TO\`) with no network switch. Walk
175
175
  one visible \`LINKED\` hop to surface actor-level exposure; never treat
176
176
  linked addresses