mrmainspring 0.1.6 → 0.1.8
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/client-setup.js +21 -2
- package/dist/config.d.ts +1 -0
- package/dist/config.js +1 -0
- package/dist/server.js +21 -1
- package/dist/x402/settlement.d.ts +9 -0
- package/dist/x402/settlement.js +39 -0
- package/package.json +1 -1
package/dist/client-setup.js
CHANGED
|
@@ -17,14 +17,21 @@ const CLIENTS = [
|
|
|
17
17
|
{ name: "Cursor", path: "%USERPROFILE%/.cursor/mcp.json", platforms: ["win32"], format: "standard" },
|
|
18
18
|
// Windsurf
|
|
19
19
|
{ name: "Windsurf", path: "~/.codeium/windsurf/mcp_config.json", platforms: ["darwin", "linux", "win32"], format: "standard" },
|
|
20
|
+
// Windsurf (also on Windows via AppData)
|
|
21
|
+
{ name: "Windsurf", path: "%APPDATA%/Windsurf/User/globalStorage/codeium.windsurf/mcp_config.json", platforms: ["win32"], format: "standard" },
|
|
20
22
|
// Zed
|
|
21
23
|
{ name: "Zed", path: "~/.config/zed/settings.json", platforms: ["darwin", "linux"], format: "zed" },
|
|
24
|
+
// Continue.dev
|
|
25
|
+
{ name: "Continue", path: "~/.continue/config.json", platforms: ["darwin", "linux", "win32"], format: "continue" },
|
|
26
|
+
// VS Code (workspace-agnostic user MCP config — requires MCP extension)
|
|
27
|
+
{ name: "VS Code", path: "~/.vscode/mcp.json", platforms: ["darwin", "linux", "win32"], format: "standard" },
|
|
22
28
|
];
|
|
23
29
|
function expandPath(p, env) {
|
|
30
|
+
const home = env.HOME ?? env.USERPROFILE ?? homedir();
|
|
24
31
|
return p
|
|
25
|
-
.replace(/^~/,
|
|
32
|
+
.replace(/^~/, home)
|
|
26
33
|
.replace(/%APPDATA%/gi, env.APPDATA ?? "")
|
|
27
|
-
.replace(/%USERPROFILE%/gi, env.USERPROFILE ??
|
|
34
|
+
.replace(/%USERPROFILE%/gi, env.USERPROFILE ?? home);
|
|
28
35
|
}
|
|
29
36
|
function isInstalled(configPath) {
|
|
30
37
|
return existsSync(dirname(configPath)) || existsSync(configPath);
|
|
@@ -43,6 +50,10 @@ function alreadySet(json, format) {
|
|
|
43
50
|
if (format === "zed") {
|
|
44
51
|
return !!json.context_servers?.mainspring;
|
|
45
52
|
}
|
|
53
|
+
if (format === "continue") {
|
|
54
|
+
const servers = json.mcpServers;
|
|
55
|
+
return !!servers?.some(s => s.name === "mainspring");
|
|
56
|
+
}
|
|
46
57
|
return !!json.mcpServers?.mainspring;
|
|
47
58
|
}
|
|
48
59
|
function mergeConfig(json, format) {
|
|
@@ -55,6 +66,14 @@ function mergeConfig(json, format) {
|
|
|
55
66
|
}
|
|
56
67
|
};
|
|
57
68
|
}
|
|
69
|
+
if (format === "continue") {
|
|
70
|
+
const existing = (json.mcpServers ?? [])
|
|
71
|
+
.filter((s) => s.name !== "mainspring");
|
|
72
|
+
return {
|
|
73
|
+
...json,
|
|
74
|
+
mcpServers: [...existing, { name: "mainspring", command: "npx", args: ["-y", "mrmainspring"] }]
|
|
75
|
+
};
|
|
76
|
+
}
|
|
58
77
|
return {
|
|
59
78
|
...json,
|
|
60
79
|
mcpServers: {
|
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);
|
package/dist/x402/settlement.js
CHANGED
|
@@ -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