chain-insights 0.27.5 → 0.31.2

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 (40) hide show
  1. package/README.md +11 -6
  2. package/dist/cli.cjs +108 -6
  3. package/dist/cli.mjs +108 -6
  4. package/dist/cli.mjs.map +1 -1
  5. package/dist/index.cjs +0 -2
  6. package/dist/index.d.cts +25 -71
  7. package/dist/index.d.cts.map +1 -1
  8. package/dist/index.d.mts +25 -71
  9. package/dist/index.d.mts.map +1 -1
  10. package/dist/index.mjs +1 -2
  11. package/dist/mcp-proxy.cjs +76 -10
  12. package/dist/mcp-proxy.d.cts +4 -5
  13. package/dist/mcp-proxy.d.cts.map +1 -1
  14. package/dist/mcp-proxy.d.mts +4 -5
  15. package/dist/mcp-proxy.d.mts.map +1 -1
  16. package/dist/mcp-proxy.mjs +76 -10
  17. package/dist/mcp-proxy.mjs.map +1 -1
  18. package/dist/{public-tools-DDGHRazh.cjs → public-tools-Id0AIPZt.cjs} +13 -175
  19. package/dist/{public-tools-CMI_0y87.mjs → public-tools-i9koK3KQ.mjs} +14 -176
  20. package/dist/public-tools-i9koK3KQ.mjs.map +1 -0
  21. package/dist/subscription-status-Cm7LqY_h.cjs +150 -0
  22. package/dist/subscription-status-MyeqOmbA.mjs +142 -0
  23. package/dist/subscription-status-MyeqOmbA.mjs.map +1 -0
  24. package/dist/{tool-visibility-CJqjmDF5.mjs → tool-visibility-CJV9HezW.mjs} +3 -2
  25. package/dist/tool-visibility-CJV9HezW.mjs.map +1 -0
  26. package/dist/{tool-visibility-BBEbpKt4.cjs → tool-visibility-CyZqYnQA.cjs} +2 -1
  27. package/dist/transport-error-CSEb6sPr.mjs +58 -0
  28. package/dist/transport-error-CSEb6sPr.mjs.map +1 -0
  29. package/dist/transport-error-DmC9WLTW.cjs +56 -0
  30. package/docs/graph-query-compatibility.md +129 -56
  31. package/docs/graph-tools.md +32 -2
  32. package/package.json +4 -4
  33. package/skills/chain-insights-cypher/SKILL.md +24 -28
  34. package/skills/chain-insights-cypher/agents/openai.yaml +2 -2
  35. package/skills/chain-insights-schema-evm/SKILL.md +52 -5
  36. package/dist/merge-BZw-pMPN.mjs +0 -199
  37. package/dist/merge-BZw-pMPN.mjs.map +0 -1
  38. package/dist/merge-C52eaAGU.cjs +0 -202
  39. package/dist/public-tools-CMI_0y87.mjs.map +0 -1
  40. package/dist/tool-visibility-CJqjmDF5.mjs.map +0 -1
package/README.md CHANGED
@@ -1,11 +1,17 @@
1
1
  # Chain Insights
2
2
 
3
+ <div align="center">
4
+ <img src=".github/assets/chain-insights-github-crime-scene.png" width="100%" alt="Chain Insights: the agency cast around a crime-scene table tracing a glowing fund-flow trail while the scammer flees with the coin" />
5
+
3
6
  [![npm version](https://img.shields.io/npm/v/chain-insights)](https://www.npmjs.com/package/chain-insights)
4
7
  [![CI](https://img.shields.io/github/actions/workflow/status/chainswarm/chain-insights/verify.yml?branch=main)](https://github.com/chainswarm/chain-insights/actions/workflows/verify.yml)
5
8
  [![OpenSSF Scorecard](https://img.shields.io/ossf-scorecard/github.com/chainswarm/chain-insights)](https://securityscorecards.dev/viewer/?uri=github.com/chainswarm/chain-insights)
6
9
  [![License](https://img.shields.io/npm/l/chain-insights)](https://github.com/chainswarm/chain-insights/blob/main/LICENSE)
7
10
 
8
- [Website](https://chain-insights.ai) | [npm](https://www.npmjs.com/package/chain-insights)
11
+ *Follow the funds. Find the obvious.*
12
+
13
+ [Website](https://chain-insights.ai) | [npm](https://www.npmjs.com/package/chain-insights) | [Quickstart](#quickstart)
14
+ </div>
9
15
 
10
16
  Chain Insights is open-source AML and forensics infrastructure for AI agents
11
17
  and analysts: a hosted Chain Insights Graph you reach over MCP, screened
@@ -124,7 +130,6 @@ Source modules (hand-maintained):
124
130
  | Module | Entrypoint | Component doc |
125
131
  | --------------- | ------------------- | ---------------------------------------------------------------------------- |
126
132
  | `config` | `src/config` | [components/config.md](docs/architecture/components/config.md) |
127
- | `federation` | `src/federation` | [components/federation.md](docs/architecture/components/federation.md) |
128
133
  | `investigation` | `src/investigation` | [components/investigation.md](docs/architecture/components/investigation.md) |
129
134
  | `mcp` | `src/mcp` | [components/mcp.md](docs/architecture/components/mcp.md) |
130
135
  | `wallet` | `src/wallet` | [components/wallet.md](docs/architecture/components/wallet.md) |
@@ -144,10 +149,10 @@ and [operating rules](docs/architecture/operating-rules.md).
144
149
 
145
150
  Graph queries choose the read graph explicitly:
146
151
 
147
- | Graph | Use it for |
148
- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
149
- | `topology` | The unified address / FLOWS_TO / LINKED graph — recent and full historical fund-flow traversal, plus the node `risk_score`/`risk_level` verdict |
150
- | `facts` | Bounded individual `TRANSFER` rows with amount, `amount_usd`, asset, transaction, and block facts |
152
+ | Graph | Use it for |
153
+ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
154
+ | `topology` | The unified address / FLOWS_TO / OPERATED_BY / LINKED graph — recent and full historical fund-flow traversal, plus the node `risk_score`/`risk_level` verdict |
155
+ | `facts` | Bounded individual `TRANSFER` rows with amount, `amount_usd`, asset, transaction, and block facts |
151
156
 
152
157
  One rule is worth reading before writing a query by hand: the `network`
153
158
  argument selects the graph, not the addresses inside it. The address-space
package/dist/cli.cjs CHANGED
@@ -187,6 +187,8 @@ async function withGraphMcpClient(name, fn) {
187
187
  const { loadConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
188
188
  const config = await loadConfig();
189
189
  const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-Ypw9BNbn.cjs")).then((n) => n.client_exports);
190
+ const { toGraphMcpEndpointError } = await Promise.resolve().then(() => require("./transport-error-DmC9WLTW.cjs"));
191
+ const endpoint = resolveGraphMcpEndpoint(config);
190
192
  const paymentFetch = await createConfiguredGraphMcpFetch(config);
191
193
  const { Client } = await import("@modelcontextprotocol/sdk/client/index.js");
192
194
  const { StreamableHTTPClientTransport } = await import("@modelcontextprotocol/sdk/client/streamableHttp.js");
@@ -194,11 +196,17 @@ async function withGraphMcpClient(name, fn) {
194
196
  name,
195
197
  version: require_version.PACKAGE_VERSION
196
198
  });
197
- await client.connect(new StreamableHTTPClientTransport(new URL(resolveGraphMcpEndpoint(config)), { fetch: paymentFetch }));
199
+ try {
200
+ await client.connect(new StreamableHTTPClientTransport(new URL(endpoint), { fetch: paymentFetch }));
201
+ } catch (err) {
202
+ throw toGraphMcpEndpointError(err, endpoint);
203
+ }
198
204
  const { installActionLogging } = await Promise.resolve().then(() => require("./action-log-HniMMF7f.cjs")).then((n) => n.action_log_exports);
199
205
  installActionLogging(client);
200
206
  try {
201
207
  return await fn(client, config);
208
+ } catch (err) {
209
+ throw toGraphMcpEndpointError(err, endpoint);
202
210
  } finally {
203
211
  await client.close();
204
212
  }
@@ -230,14 +238,74 @@ async function printNetworkCapability(name, opts) {
230
238
  if (opts.json) console.log(JSON.stringify(network, null, 2));
231
239
  else console.log(formatNetworkCapability(network));
232
240
  }
241
+ /**
242
+ * Fetches the caller's subscription facts for the deposit pre-sign guard.
243
+ * The extension math is server-authoritative: the printed values come from
244
+ * `subscription_status`. Any failure (no wallet, unreachable endpoint,
245
+ * missing tool, error result) degrades to an unavailable lookup — the guard
246
+ * must never block the flow on a server that lacks the tool.
247
+ */
248
+ async function fetchSubscriptionStatusForCli() {
249
+ try {
250
+ const { getWalletAccount } = await Promise.resolve().then(() => require("./tools-BHfphgy9.cjs")).then((n) => n.tools_exports);
251
+ const account = await getWalletAccount();
252
+ return await withGraphMcpClient("chain-insights-cli-subscription-status", async (client) => {
253
+ const result = await client.callTool({
254
+ name: "subscription_status",
255
+ arguments: { wallet: account.address }
256
+ });
257
+ const { parseSubscriptionStatusToolResult } = await Promise.resolve().then(() => require("./subscription-status-Cm7LqY_h.cjs")).then((n) => n.subscription_status_exports);
258
+ const facts = parseSubscriptionStatusToolResult(result);
259
+ if (!facts) return {
260
+ kind: "unavailable",
261
+ reason: "the graph endpoint returned no subscription facts"
262
+ };
263
+ return {
264
+ kind: "available",
265
+ facts
266
+ };
267
+ });
268
+ } catch (err) {
269
+ return {
270
+ kind: "unavailable",
271
+ reason: err.message
272
+ };
273
+ }
274
+ }
275
+ async function printSubscriptionPassGuidance(pass) {
276
+ const { formatDepositGuardLine, formatDepositIrreversibilityWarning, formatSubscriptionPassHint, isDepositConfirmed, resolveSubscriptionMonthUsd } = await Promise.resolve().then(() => require("./subscription-status-Cm7LqY_h.cjs")).then((n) => n.subscription_status_exports);
277
+ const hint = formatSubscriptionPassHint(pass, resolveSubscriptionMonthUsd());
278
+ const status = await fetchSubscriptionStatusForCli();
279
+ if (status.kind === "available") {
280
+ process.stderr.write(`${formatDepositGuardLine(status.facts, pass)}\n`);
281
+ process.stderr.write("The no-admin subscription sink cannot refund deposits. Type DEPOSIT to continue:\n");
282
+ const { createInterface } = await import("node:readline/promises");
283
+ const prompt = createInterface({
284
+ input: process.stdin,
285
+ output: process.stderr
286
+ });
287
+ let answer;
288
+ try {
289
+ answer = await prompt.question("> ");
290
+ } finally {
291
+ prompt.close();
292
+ }
293
+ process.stderr.write("\n");
294
+ if (!isDepositConfirmed(answer)) throw new Error("Deposit cancelled. No deposit was made.");
295
+ console.log(hint);
296
+ return;
297
+ }
298
+ process.stderr.write(`${formatDepositIrreversibilityWarning(status.reason)}\n`);
299
+ console.log(hint);
300
+ }
233
301
  function addAmlAddressRiskCommand(parent, networksCommand) {
234
302
  parent.addCommand(createCliCommand("aml-address-risk").description("CIA workflow: screen an address for AML risk, exchange behavior, and optional comparison with another address").requiredOption("--address <address>", "Full blockchain address to screen").requiredOption("--network <network>", `Network to query. Run \`${networksCommand}\` for supported networks.`).option("--compare-address <address>", "Optional second address to compare against the screened address").option("--json", "Print machine-readable JSON output").option("--version <version>", "AML tool contract version. Omit to use the latest version (currently v1)").addOption(new commander.Option("--tool-version <version>", "Internal alias for the AML tool version").hideHelp()).action(async (opts) => {
235
303
  try {
236
- const { resolveAmlAddressRiskVersion } = await Promise.resolve().then(() => require("./public-tools-DDGHRazh.cjs"));
304
+ const { resolveAmlAddressRiskVersion } = await Promise.resolve().then(() => require("./public-tools-Id0AIPZt.cjs"));
237
305
  const requestedVersion = opts.toolVersion ?? opts.version;
238
306
  resolveAmlAddressRiskVersion(requestedVersion);
239
307
  await withGraphMcpClient("chain-insights-cli-aml-address-risk", async (client) => {
240
- const { runAmlAddressRisk } = await Promise.resolve().then(() => require("./public-tools-DDGHRazh.cjs"));
308
+ const { runAmlAddressRisk } = await Promise.resolve().then(() => require("./public-tools-Id0AIPZt.cjs"));
241
309
  const result = await runAmlAddressRisk(client, {
242
310
  address: opts.address,
243
311
  network: opts.network,
@@ -534,6 +602,21 @@ program.command("wallet").description("Manage the local Base USDC payment wallet
534
602
  process.exit(1);
535
603
  }
536
604
  }));
605
+ program.command("buy").description("Show CIA subscription pass deposit guidance (the sink cannot refund deposits)").addCommand(createCliCommand("day").description("Show day-pass deposit guidance (SUBSCRIPTION_MONTH_USD / 30)").action(async () => {
606
+ try {
607
+ await printSubscriptionPassGuidance("day");
608
+ } catch (err) {
609
+ console.error(err.message);
610
+ process.exit(1);
611
+ }
612
+ })).addCommand(createCliCommand("month").description("Show month-pass deposit guidance at the list price").action(async () => {
613
+ try {
614
+ await printSubscriptionPassGuidance("month");
615
+ } catch (err) {
616
+ console.error(err.message);
617
+ process.exit(1);
618
+ }
619
+ }));
537
620
  program.command("mcp").description("Low-level access to the Chain Insights MCP endpoint").allowExcessArguments(false).addCommand(createCliCommand("networks").description("List the detailed Chain Insights capability matrix and tool support").option("--json", "Print raw capability JSON").action(async (opts) => {
538
621
  try {
539
622
  await printNetworkCapabilities(opts);
@@ -545,7 +628,7 @@ program.command("mcp").description("Low-level access to the Chain Insights MCP e
545
628
  try {
546
629
  const { loadSchema, saveSchema } = await Promise.resolve().then(() => require("./schema-cache-n7Gbhvsj.cjs"));
547
630
  const { formatToolsTable } = await Promise.resolve().then(() => require("./format-BjZuYDr8.cjs"));
548
- const { visibleRemoteTools } = await Promise.resolve().then(() => require("./tool-visibility-BBEbpKt4.cjs")).then((n) => n.tool_visibility_exports);
631
+ const { visibleRemoteTools } = await Promise.resolve().then(() => require("./tool-visibility-CyZqYnQA.cjs")).then((n) => n.tool_visibility_exports);
549
632
  const { loadConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
550
633
  const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-Ypw9BNbn.cjs")).then((n) => n.client_exports);
551
634
  const config = await loadConfig();
@@ -575,7 +658,7 @@ program.command("mcp").description("Low-level access to the Chain Insights MCP e
575
658
  })).addCommand(createCliCommand("call").description("Call a low-level MCP tool directly (advanced)").option("--json", "Print machine-readable JSON output").argument("<tool>", "Tool name to call").argument("[args...]", "Key=value arguments (e.g. address=0x1234... network=robinhood)").action(async (tool, rawArgs, opts) => {
576
659
  try {
577
660
  const { parseMcpCallArgs } = await Promise.resolve().then(() => require("./call-args-DAiQSDmD.cjs"));
578
- const { assertPublicMcpToolName, validatePublicMcpToolArguments } = await Promise.resolve().then(() => require("./tool-visibility-BBEbpKt4.cjs")).then((n) => n.tool_visibility_exports);
661
+ const { assertPublicMcpToolName, validatePublicMcpToolArguments } = await Promise.resolve().then(() => require("./tool-visibility-CyZqYnQA.cjs")).then((n) => n.tool_visibility_exports);
579
662
  const args = parseMcpCallArgs(rawArgs);
580
663
  assertPublicMcpToolName(tool);
581
664
  if (tool === "aml_address_risk") throw new Error("aml_address_risk is a CIA workflow. Run `cia workflow aml-address-risk` instead.");
@@ -611,6 +694,25 @@ program.command("mcp").description("Low-level access to the Chain Insights MCP e
611
694
  }
612
695
  return;
613
696
  }
697
+ if (tool === "meta_subscription_status") {
698
+ try {
699
+ const { getWalletAccount } = await Promise.resolve().then(() => require("./tools-BHfphgy9.cjs")).then((n) => n.tools_exports);
700
+ const account = await getWalletAccount();
701
+ printMcpTextContent(await client.callTool({
702
+ name: "subscription_status",
703
+ arguments: { wallet: account.address }
704
+ }), {
705
+ tool,
706
+ json: opts.json
707
+ });
708
+ } catch (err) {
709
+ const { isMissingSubscriptionStatusToolError, unavailableSubscriptionStatus, subscriptionStatusText } = await Promise.resolve().then(() => require("./subscription-status-Cm7LqY_h.cjs")).then((n) => n.subscription_status_exports);
710
+ if (!isMissingSubscriptionStatusToolError(err)) throw err;
711
+ const { resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-Ypw9BNbn.cjs")).then((n) => n.client_exports);
712
+ console.log(subscriptionStatusText(unavailableSubscriptionStatus(resolveGraphMcpEndpoint(config), `subscription_status failed: ${err.message}`)));
713
+ }
714
+ return;
715
+ }
614
716
  printMcpTextContent(await client.callTool({
615
717
  name: tool,
616
718
  arguments: args
@@ -620,7 +722,7 @@ program.command("mcp").description("Low-level access to the Chain Insights MCP e
620
722
  });
621
723
  });
622
724
  } catch (err) {
623
- const { formatMcpCallError } = await Promise.resolve().then(() => require("./tool-visibility-BBEbpKt4.cjs")).then((n) => n.tool_visibility_exports);
725
+ const { formatMcpCallError } = await Promise.resolve().then(() => require("./tool-visibility-CyZqYnQA.cjs")).then((n) => n.tool_visibility_exports);
624
726
  console.error(formatMcpCallError(tool, err));
625
727
  process.exit(1);
626
728
  }
package/dist/cli.mjs CHANGED
@@ -185,6 +185,8 @@ async function withGraphMcpClient(name, fn) {
185
185
  const { loadConfig } = await import("./config-DbbPiGk0.mjs").then((n) => n.t);
186
186
  const config = await loadConfig();
187
187
  const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await import("./client-CHYskPnG.mjs").then((n) => n.r);
188
+ const { toGraphMcpEndpointError } = await import("./transport-error-CSEb6sPr.mjs");
189
+ const endpoint = resolveGraphMcpEndpoint(config);
188
190
  const paymentFetch = await createConfiguredGraphMcpFetch(config);
189
191
  const { Client } = await import("@modelcontextprotocol/sdk/client/index.js");
190
192
  const { StreamableHTTPClientTransport } = await import("@modelcontextprotocol/sdk/client/streamableHttp.js");
@@ -192,11 +194,17 @@ async function withGraphMcpClient(name, fn) {
192
194
  name,
193
195
  version: PACKAGE_VERSION
194
196
  });
195
- await client.connect(new StreamableHTTPClientTransport(new URL(resolveGraphMcpEndpoint(config)), { fetch: paymentFetch }));
197
+ try {
198
+ await client.connect(new StreamableHTTPClientTransport(new URL(endpoint), { fetch: paymentFetch }));
199
+ } catch (err) {
200
+ throw toGraphMcpEndpointError(err, endpoint);
201
+ }
196
202
  const { installActionLogging } = await import("./action-log-diTHyMbV.mjs").then((n) => n.n);
197
203
  installActionLogging(client);
198
204
  try {
199
205
  return await fn(client, config);
206
+ } catch (err) {
207
+ throw toGraphMcpEndpointError(err, endpoint);
200
208
  } finally {
201
209
  await client.close();
202
210
  }
@@ -228,14 +236,74 @@ async function printNetworkCapability(name, opts) {
228
236
  if (opts.json) console.log(JSON.stringify(network, null, 2));
229
237
  else console.log(formatNetworkCapability(network));
230
238
  }
239
+ /**
240
+ * Fetches the caller's subscription facts for the deposit pre-sign guard.
241
+ * The extension math is server-authoritative: the printed values come from
242
+ * `subscription_status`. Any failure (no wallet, unreachable endpoint,
243
+ * missing tool, error result) degrades to an unavailable lookup — the guard
244
+ * must never block the flow on a server that lacks the tool.
245
+ */
246
+ async function fetchSubscriptionStatusForCli() {
247
+ try {
248
+ const { getWalletAccount } = await import("./tools-BRQAPF2R.mjs").then((n) => n.p);
249
+ const account = await getWalletAccount();
250
+ return await withGraphMcpClient("chain-insights-cli-subscription-status", async (client) => {
251
+ const result = await client.callTool({
252
+ name: "subscription_status",
253
+ arguments: { wallet: account.address }
254
+ });
255
+ const { parseSubscriptionStatusToolResult } = await import("./subscription-status-MyeqOmbA.mjs").then((n) => n.t);
256
+ const facts = parseSubscriptionStatusToolResult(result);
257
+ if (!facts) return {
258
+ kind: "unavailable",
259
+ reason: "the graph endpoint returned no subscription facts"
260
+ };
261
+ return {
262
+ kind: "available",
263
+ facts
264
+ };
265
+ });
266
+ } catch (err) {
267
+ return {
268
+ kind: "unavailable",
269
+ reason: err.message
270
+ };
271
+ }
272
+ }
273
+ async function printSubscriptionPassGuidance(pass) {
274
+ const { formatDepositGuardLine, formatDepositIrreversibilityWarning, formatSubscriptionPassHint, isDepositConfirmed, resolveSubscriptionMonthUsd } = await import("./subscription-status-MyeqOmbA.mjs").then((n) => n.t);
275
+ const hint = formatSubscriptionPassHint(pass, resolveSubscriptionMonthUsd());
276
+ const status = await fetchSubscriptionStatusForCli();
277
+ if (status.kind === "available") {
278
+ process.stderr.write(`${formatDepositGuardLine(status.facts, pass)}\n`);
279
+ process.stderr.write("The no-admin subscription sink cannot refund deposits. Type DEPOSIT to continue:\n");
280
+ const { createInterface } = await import("node:readline/promises");
281
+ const prompt = createInterface({
282
+ input: process.stdin,
283
+ output: process.stderr
284
+ });
285
+ let answer;
286
+ try {
287
+ answer = await prompt.question("> ");
288
+ } finally {
289
+ prompt.close();
290
+ }
291
+ process.stderr.write("\n");
292
+ if (!isDepositConfirmed(answer)) throw new Error("Deposit cancelled. No deposit was made.");
293
+ console.log(hint);
294
+ return;
295
+ }
296
+ process.stderr.write(`${formatDepositIrreversibilityWarning(status.reason)}\n`);
297
+ console.log(hint);
298
+ }
231
299
  function addAmlAddressRiskCommand(parent, networksCommand) {
232
300
  parent.addCommand(createCliCommand("aml-address-risk").description("CIA workflow: screen an address for AML risk, exchange behavior, and optional comparison with another address").requiredOption("--address <address>", "Full blockchain address to screen").requiredOption("--network <network>", `Network to query. Run \`${networksCommand}\` for supported networks.`).option("--compare-address <address>", "Optional second address to compare against the screened address").option("--json", "Print machine-readable JSON output").option("--version <version>", "AML tool contract version. Omit to use the latest version (currently v1)").addOption(new Option("--tool-version <version>", "Internal alias for the AML tool version").hideHelp()).action(async (opts) => {
233
301
  try {
234
- const { resolveAmlAddressRiskVersion } = await import("./public-tools-CMI_0y87.mjs");
302
+ const { resolveAmlAddressRiskVersion } = await import("./public-tools-i9koK3KQ.mjs");
235
303
  const requestedVersion = opts.toolVersion ?? opts.version;
236
304
  resolveAmlAddressRiskVersion(requestedVersion);
237
305
  await withGraphMcpClient("chain-insights-cli-aml-address-risk", async (client) => {
238
- const { runAmlAddressRisk } = await import("./public-tools-CMI_0y87.mjs");
306
+ const { runAmlAddressRisk } = await import("./public-tools-i9koK3KQ.mjs");
239
307
  const result = await runAmlAddressRisk(client, {
240
308
  address: opts.address,
241
309
  network: opts.network,
@@ -532,6 +600,21 @@ program.command("wallet").description("Manage the local Base USDC payment wallet
532
600
  process.exit(1);
533
601
  }
534
602
  }));
603
+ program.command("buy").description("Show CIA subscription pass deposit guidance (the sink cannot refund deposits)").addCommand(createCliCommand("day").description("Show day-pass deposit guidance (SUBSCRIPTION_MONTH_USD / 30)").action(async () => {
604
+ try {
605
+ await printSubscriptionPassGuidance("day");
606
+ } catch (err) {
607
+ console.error(err.message);
608
+ process.exit(1);
609
+ }
610
+ })).addCommand(createCliCommand("month").description("Show month-pass deposit guidance at the list price").action(async () => {
611
+ try {
612
+ await printSubscriptionPassGuidance("month");
613
+ } catch (err) {
614
+ console.error(err.message);
615
+ process.exit(1);
616
+ }
617
+ }));
535
618
  program.command("mcp").description("Low-level access to the Chain Insights MCP endpoint").allowExcessArguments(false).addCommand(createCliCommand("networks").description("List the detailed Chain Insights capability matrix and tool support").option("--json", "Print raw capability JSON").action(async (opts) => {
536
619
  try {
537
620
  await printNetworkCapabilities(opts);
@@ -543,7 +626,7 @@ program.command("mcp").description("Low-level access to the Chain Insights MCP e
543
626
  try {
544
627
  const { loadSchema, saveSchema } = await import("./schema-cache-DJdU4MIP.mjs");
545
628
  const { formatToolsTable } = await import("./format-DB2IH2U5.mjs");
546
- const { visibleRemoteTools } = await import("./tool-visibility-CJqjmDF5.mjs").then((n) => n.i);
629
+ const { visibleRemoteTools } = await import("./tool-visibility-CJV9HezW.mjs").then((n) => n.i);
547
630
  const { loadConfig } = await import("./config-DbbPiGk0.mjs").then((n) => n.t);
548
631
  const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await import("./client-CHYskPnG.mjs").then((n) => n.r);
549
632
  const config = await loadConfig();
@@ -573,7 +656,7 @@ program.command("mcp").description("Low-level access to the Chain Insights MCP e
573
656
  })).addCommand(createCliCommand("call").description("Call a low-level MCP tool directly (advanced)").option("--json", "Print machine-readable JSON output").argument("<tool>", "Tool name to call").argument("[args...]", "Key=value arguments (e.g. address=0x1234... network=robinhood)").action(async (tool, rawArgs, opts) => {
574
657
  try {
575
658
  const { parseMcpCallArgs } = await import("./call-args-ysbB_xdA.mjs");
576
- const { assertPublicMcpToolName, validatePublicMcpToolArguments } = await import("./tool-visibility-CJqjmDF5.mjs").then((n) => n.i);
659
+ const { assertPublicMcpToolName, validatePublicMcpToolArguments } = await import("./tool-visibility-CJV9HezW.mjs").then((n) => n.i);
577
660
  const args = parseMcpCallArgs(rawArgs);
578
661
  assertPublicMcpToolName(tool);
579
662
  if (tool === "aml_address_risk") throw new Error("aml_address_risk is a CIA workflow. Run `cia workflow aml-address-risk` instead.");
@@ -609,6 +692,25 @@ program.command("mcp").description("Low-level access to the Chain Insights MCP e
609
692
  }
610
693
  return;
611
694
  }
695
+ if (tool === "meta_subscription_status") {
696
+ try {
697
+ const { getWalletAccount } = await import("./tools-BRQAPF2R.mjs").then((n) => n.p);
698
+ const account = await getWalletAccount();
699
+ printMcpTextContent(await client.callTool({
700
+ name: "subscription_status",
701
+ arguments: { wallet: account.address }
702
+ }), {
703
+ tool,
704
+ json: opts.json
705
+ });
706
+ } catch (err) {
707
+ const { isMissingSubscriptionStatusToolError, unavailableSubscriptionStatus, subscriptionStatusText } = await import("./subscription-status-MyeqOmbA.mjs").then((n) => n.t);
708
+ if (!isMissingSubscriptionStatusToolError(err)) throw err;
709
+ const { resolveGraphMcpEndpoint } = await import("./client-CHYskPnG.mjs").then((n) => n.r);
710
+ console.log(subscriptionStatusText(unavailableSubscriptionStatus(resolveGraphMcpEndpoint(config), `subscription_status failed: ${err.message}`)));
711
+ }
712
+ return;
713
+ }
612
714
  printMcpTextContent(await client.callTool({
613
715
  name: tool,
614
716
  arguments: args
@@ -618,7 +720,7 @@ program.command("mcp").description("Low-level access to the Chain Insights MCP e
618
720
  });
619
721
  });
620
722
  } catch (err) {
621
- const { formatMcpCallError } = await import("./tool-visibility-CJqjmDF5.mjs").then((n) => n.i);
723
+ const { formatMcpCallError } = await import("./tool-visibility-CJV9HezW.mjs").then((n) => n.i);
622
724
  console.error(formatMcpCallError(tool, err));
623
725
  process.exit(1);
624
726
  }