mrmainspring 0.1.7 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -65,8 +65,15 @@ export function runCliCommand(args) {
65
65
  process.stdout.write(report);
66
66
  }
67
67
  else {
68
- process.stdout.write("\nNo MCP clients detected. Paste this into your client config manually:\n\n");
68
+ process.stdout.write("\nNo MCP clients detected automatically.\n" +
69
+ "Add this to your MCP client config (Claude Desktop, Cursor, Windsurf, Zed, VS Code, Continue, or any MCP host):\n\n");
69
70
  process.stdout.write(`${formatMcpConfig()}\n`);
71
+ process.stdout.write("\nConfig file locations:\n" +
72
+ " Claude Desktop ~/Library/Application Support/Claude/claude_desktop_config.json\n" +
73
+ " Cursor ~/.cursor/mcp.json\n" +
74
+ " Windsurf ~/.codeium/windsurf/mcp_config.json\n" +
75
+ " Zed ~/.config/zed/settings.json (context_servers format)\n" +
76
+ " VS Code ~/.vscode/mcp.json\n\n");
70
77
  }
71
78
  return true;
72
79
  }
package/dist/config.d.ts CHANGED
@@ -23,6 +23,7 @@ export type X402Config = {
23
23
  signerUrl: string | null;
24
24
  signerAuthToken: string | null;
25
25
  signerTimeoutMs: number;
26
+ buyerAccountHash: string | null;
26
27
  paymentHeaderName: string;
27
28
  casperSettlementPaymentAmountMotes: string;
28
29
  casperConfirmationPollIntervalMs: number;
package/dist/config.js CHANGED
@@ -31,6 +31,7 @@ export function loadConfig(env = process.env) {
31
31
  signerUrl: optionalEnv(env.X402_SIGNER_URL),
32
32
  signerAuthToken: optionalEnv(env.X402_SIGNER_AUTH_TOKEN),
33
33
  signerTimeoutMs: parsePositiveInteger(env.X402_SIGNER_TIMEOUT_MS, "X402_SIGNER_TIMEOUT_MS", 10_000),
34
+ buyerAccountHash: optionalEnv(env.X402_BUYER_ACCOUNT_HASH),
34
35
  paymentHeaderName: optionalEnv(env.X402_PAYMENT_HEADER_NAME) ?? "PAYMENT-SIGNATURE",
35
36
  casperSettlementPaymentAmountMotes: optionalEnv(env.X402_CASPER_SETTLEMENT_PAYMENT_AMOUNT_MOTES) ?? "7000000000",
36
37
  casperConfirmationPollIntervalMs: parsePositiveInteger(env.X402_CASPER_CONFIRMATION_POLL_INTERVAL_MS, "X402_CASPER_CONFIRMATION_POLL_INTERVAL_MS", 2_000),
package/dist/server.js CHANGED
@@ -10,7 +10,7 @@ import { MemoryService } from "./memory/service.js";
10
10
  import { PaymentService } from "./payments/service.js";
11
11
  import { createBackendStores } from "./storage/store-factory.js";
12
12
  import { X402ChallengeClient } from "./x402/client.js";
13
- import { CasperCliX402SettlementProvider, DisabledX402SettlementProvider, FacilitatorX402SettlementProvider, HttpX402SigningProvider, ResourceRetryX402SettlementProvider } from "./x402/settlement.js";
13
+ import { CasperCliX402SettlementProvider, DisabledX402SettlementProvider, FacilitatorX402SettlementProvider, HttpX402SigningProvider, LocalCasperX402SigningProvider, ResourceRetryX402SettlementProvider } from "./x402/settlement.js";
14
14
  export function createSigilServer(config) {
15
15
  const server = new McpServer({
16
16
  name: config.serverName,
@@ -35,6 +35,26 @@ export function createX402SettlementProvider(config) {
35
35
  if (!config.x402.settlementEnabled) {
36
36
  return new DisabledX402SettlementProvider("x402_settlement_disabled");
37
37
  }
38
+ if (config.x402.settlementMode === "casper-cli" && !config.x402.signerUrl) {
39
+ const localSigner = new LocalCasperX402SigningProvider({
40
+ accountKeyPath: config.casper.accountKeyPath ?? "",
41
+ buyerAccountHash: config.x402.buyerAccountHash
42
+ });
43
+ return new CasperCliX402SettlementProvider(localSigner, {
44
+ networkName: config.casper.networkName,
45
+ caip2ChainId: config.casper.caip2ChainId,
46
+ rpcUrl: config.casper.rpcUrl,
47
+ accountKeyPath: config.casper.accountKeyPath,
48
+ submissionEnabled: config.casper.submissionEnabled,
49
+ clientBin: config.casper.clientBin,
50
+ clientWslDistro: config.casper.clientWslDistro,
51
+ gasPriceTolerance: config.casper.gasPriceTolerance,
52
+ pricingMode: config.casper.pricingMode,
53
+ paymentAmountMotes: config.x402.casperSettlementPaymentAmountMotes,
54
+ confirmationPollIntervalMs: config.x402.casperConfirmationPollIntervalMs,
55
+ confirmationTimeoutMs: config.x402.casperConfirmationTimeoutMs
56
+ });
57
+ }
38
58
  if (!config.x402.signerUrl) {
39
59
  return new DisabledX402SettlementProvider("x402_signing_provider_not_configured");
40
60
  }
@@ -122,6 +122,15 @@ export declare class DisabledX402SettlementProvider implements X402SettlementPro
122
122
  export declare class DisabledX402SigningProvider implements X402SignedPaymentProvider {
123
123
  sign(): Promise<X402SigningResult>;
124
124
  }
125
+ export type LocalCasperX402SigningProviderConfig = {
126
+ accountKeyPath: string;
127
+ buyerAccountHash: string | null;
128
+ };
129
+ export declare class LocalCasperX402SigningProvider implements X402SignedPaymentProvider {
130
+ private readonly config;
131
+ constructor(config: LocalCasperX402SigningProviderConfig);
132
+ sign(input: X402SigningInput): Promise<X402SigningResult>;
133
+ }
125
134
  export declare class HttpX402SigningProvider implements X402SignedPaymentProvider {
126
135
  private readonly config;
127
136
  constructor(config: X402HttpSigningProviderConfig);
@@ -4,6 +4,7 @@ import { canonicalizeJson, toJsonObject, toJsonValue } from "../memory/canonical
4
4
  import { sha256Hex } from "../memory/hash.js";
5
5
  import { redactX402Value } from "./redaction.js";
6
6
  import { validateX402PaymentPayload, verifyX402SettlementResponse } from "./readiness.js";
7
+ import { loadCasperSigningKeyFromFile, signX402PaymentPayload } from "./signer.js";
7
8
  export class DisabledX402SettlementProvider {
8
9
  blocker;
9
10
  constructor(blocker = "x402_settlement_disabled") {
@@ -34,6 +35,44 @@ export class DisabledX402SigningProvider {
34
35
  };
35
36
  }
36
37
  }
38
+ export class LocalCasperX402SigningProvider {
39
+ config;
40
+ constructor(config) {
41
+ this.config = config;
42
+ }
43
+ async sign(input) {
44
+ let signingKey;
45
+ try {
46
+ signingKey = loadCasperSigningKeyFromFile(this.config.accountKeyPath);
47
+ }
48
+ catch {
49
+ return { signed: false, blocker: "x402_signing_provider_not_configured" };
50
+ }
51
+ // Ed25519 publicKey is `01<32-byte-hex>` — accepted directly as account identifier
52
+ const buyerAccountHash = this.config.buyerAccountHash ??
53
+ (signingKey.algorithm === "ed25519" ? signingKey.publicKey : null);
54
+ if (!buyerAccountHash) {
55
+ return { signed: false, blocker: "x402_signing_provider_not_configured" };
56
+ }
57
+ const result = signX402PaymentPayload({
58
+ payment_id: input.payment_id,
59
+ facilitator_url: input.facilitator_url,
60
+ method: input.method,
61
+ url: input.url,
62
+ selected_requirement: input.selected_requirement,
63
+ selected_requirement_hash: input.selected_requirement_hash,
64
+ policy_hash: input.policy_hash
65
+ }, { signingKey, buyerAccountHash });
66
+ if (!result.signed) {
67
+ return { signed: false, blocker: "x402_signer_response_invalid" };
68
+ }
69
+ return {
70
+ signed: true,
71
+ signed_payload: result.signed_payload,
72
+ signed_payload_hash: createSignedPayloadHash(result.signed_payload)
73
+ };
74
+ }
75
+ }
37
76
  export class HttpX402SigningProvider {
38
77
  config;
39
78
  constructor(config) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mrmainspring",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "Mr Mainspring MCP backend with memory, Grimoire policies, audit, Casper anchoring, and x402 settlement boundaries.",
5
5
  "license": "MIT",
6
6
  "type": "module",