crossmint-wallets-mcp 0.1.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 (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +303 -0
  3. package/dist/core/client.d.ts +24 -0
  4. package/dist/core/client.d.ts.map +1 -0
  5. package/dist/core/client.js +51 -0
  6. package/dist/core/client.js.map +1 -0
  7. package/dist/core/create-wallet.d.ts +17 -0
  8. package/dist/core/create-wallet.d.ts.map +1 -0
  9. package/dist/core/create-wallet.js +44 -0
  10. package/dist/core/create-wallet.js.map +1 -0
  11. package/dist/core/get-balance.d.ts +16 -0
  12. package/dist/core/get-balance.d.ts.map +1 -0
  13. package/dist/core/get-balance.js +31 -0
  14. package/dist/core/get-balance.js.map +1 -0
  15. package/dist/core/pay-x402-endpoint.d.ts +36 -0
  16. package/dist/core/pay-x402-endpoint.d.ts.map +1 -0
  17. package/dist/core/pay-x402-endpoint.js +189 -0
  18. package/dist/core/pay-x402-endpoint.js.map +1 -0
  19. package/dist/core/transfer-token.d.ts +20 -0
  20. package/dist/core/transfer-token.d.ts.map +1 -0
  21. package/dist/core/transfer-token.js +33 -0
  22. package/dist/core/transfer-token.js.map +1 -0
  23. package/dist/core/types.d.ts +46 -0
  24. package/dist/core/types.d.ts.map +1 -0
  25. package/dist/core/types.js +6 -0
  26. package/dist/core/types.js.map +1 -0
  27. package/dist/index.d.ts +14 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +13 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/mcp/errors.d.ts +23 -0
  32. package/dist/mcp/errors.d.ts.map +1 -0
  33. package/dist/mcp/errors.js +34 -0
  34. package/dist/mcp/errors.js.map +1 -0
  35. package/dist/mcp/server.d.ts +16 -0
  36. package/dist/mcp/server.d.ts.map +1 -0
  37. package/dist/mcp/server.js +34 -0
  38. package/dist/mcp/server.js.map +1 -0
  39. package/dist/mcp/tools.d.ts +3 -0
  40. package/dist/mcp/tools.d.ts.map +1 -0
  41. package/dist/mcp/tools.js +198 -0
  42. package/dist/mcp/tools.js.map +1 -0
  43. package/package.json +64 -0
@@ -0,0 +1,189 @@
1
+ import { getConfig, getWalletsClient } from "./client.js";
2
+ import { getExplorerLink } from "./create-wallet.js";
3
+ // ---------------------------------------------------------------------------
4
+ // Chain / network mapping
5
+ // ---------------------------------------------------------------------------
6
+ // Maps x402 network identifiers (CAIP-2 or v1 shorthand) to the chain name
7
+ // that the Crossmint SDK's wallet uses. Only Solana mainnet is wired up in
8
+ // v0.1; EVM support is a stretch goal for later phases.
9
+ function resolveChain(network) {
10
+ const lower = network.toLowerCase();
11
+ if (lower === "solana" || lower.startsWith("solana:"))
12
+ return "solana";
13
+ if (lower === "base" || lower === "eip155:8453")
14
+ return "base";
15
+ if (lower === "base-sepolia" || lower === "eip155:84532")
16
+ return "base-sepolia";
17
+ return null;
18
+ }
19
+ // Map an asset identifier (mint address or symbol) to the Crossmint SDK's
20
+ // send() token argument. The SDK accepts either a mint address or a symbol
21
+ // like "usdc"; symbols are safer because the SDK resolves the network-
22
+ // correct mint internally.
23
+ function resolveTokenSymbol(asset) {
24
+ const USDC_MAINNET_MINT = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
25
+ if (asset === USDC_MAINNET_MINT)
26
+ return "usdc";
27
+ if (asset.toLowerCase() === "usdc")
28
+ return "usdc";
29
+ // Fall back to passing the mint/address through as-is
30
+ return asset;
31
+ }
32
+ // ---------------------------------------------------------------------------
33
+ // Amount conversion
34
+ // ---------------------------------------------------------------------------
35
+ // Atomic units → decimal string for a given number of decimals. The Crossmint
36
+ // SDK's send() method expects the amount in decimal units (e.g. "0.01" for
37
+ // 1¢ of USDC), not atomic units.
38
+ function atomicToDecimal(atomic, decimals) {
39
+ const n = BigInt(atomic);
40
+ const base = BigInt(10) ** BigInt(decimals);
41
+ const whole = n / base;
42
+ const frac = n % base;
43
+ if (frac === 0n)
44
+ return whole.toString();
45
+ const fracStr = frac.toString().padStart(decimals, "0").replace(/0+$/, "");
46
+ return `${whole}.${fracStr}`;
47
+ }
48
+ // ---------------------------------------------------------------------------
49
+ // Main entry point
50
+ // ---------------------------------------------------------------------------
51
+ /**
52
+ * Pay an x402-protected HTTP endpoint using a Crossmint smart wallet.
53
+ *
54
+ * Flow:
55
+ * 1. Fetch `url` with the caller's original headers/body
56
+ * 2. If the server responds 200, return directly — nothing to pay
57
+ * 3. If the server responds 402, parse the PaymentRequired body and pick
58
+ * the first PaymentRequirements entry on a supported chain (Solana
59
+ * mainnet in v0.1)
60
+ * 4. Load the payer wallet via `wallets.getWallet(payerAddress, ...)`,
61
+ * passing the server recovery signer through the args so the
62
+ * returned Wallet has its `#recovery` field populated. Without this,
63
+ * the SDK's useSigner path crashes because `isRecoverySigner` tries
64
+ * to call `.startsWith` on an undefined secret (chunk-XNZLCUTY:395).
65
+ * The WalletArgsFor TypeScript type doesn't declare a `recovery`
66
+ * field, but the runtime `createWalletInstance` reads it when
67
+ * present, so we pass it via an explicit cast.
68
+ * 5. Call `wallet.send(payTo, tokenSymbol, decimalAmount)` — Crossmint
69
+ * handles the CPI inner instruction wrapping, signing via the server
70
+ * recovery signer, fee payment, and confirmation internally
71
+ * 6. Build the X-PAYMENT header as base64(JSON(PaymentPayload)) with the
72
+ * resulting transaction signature in the payload
73
+ * 7. Retry the original request with the X-PAYMENT header appended
74
+ * 8. Return the response body plus the on-chain tx signature
75
+ */
76
+ export async function payX402Endpoint(opts) {
77
+ const { url, payerAddress, chain, headers = {}, method = "GET", jsonBody, maxUsdcAtomic, } = opts;
78
+ // -----------------------------------------------------------------------
79
+ // Step 1: initial request — expect 402
80
+ // -----------------------------------------------------------------------
81
+ const initialResponse = await fetchWith(url, method, headers, jsonBody);
82
+ if (initialResponse.status !== 402) {
83
+ if (initialResponse.status >= 200 && initialResponse.status < 300) {
84
+ return {
85
+ url,
86
+ transactionSignature: "",
87
+ responseStatus: initialResponse.status,
88
+ responseBody: await safeJson(initialResponse),
89
+ explorerLink: "",
90
+ };
91
+ }
92
+ throw new Error(`Expected 200 or 402 on initial request, got ${initialResponse.status}`);
93
+ }
94
+ // -----------------------------------------------------------------------
95
+ // Step 2: parse the PaymentRequired body
96
+ // -----------------------------------------------------------------------
97
+ const paymentRequired = (await initialResponse.json());
98
+ if (!paymentRequired.accepts?.length) {
99
+ throw new Error("402 response has no accepts[] entries");
100
+ }
101
+ // Pick the first requirement whose network we support
102
+ const requirement = paymentRequired.accepts.find((r) => resolveChain(r.network) !== null);
103
+ if (!requirement) {
104
+ const offered = paymentRequired.accepts.map((r) => r.network).join(", ");
105
+ throw new Error(`No supported payment network in 402 response. Offered: [${offered}]. ` +
106
+ `Supported: solana (mainnet).`);
107
+ }
108
+ const resolvedChain = resolveChain(requirement.network);
109
+ if (resolvedChain !== chain) {
110
+ throw new Error(`402 requires payment on ${resolvedChain} but caller chain is ${chain}`);
111
+ }
112
+ // Enforce max payment guardrail
113
+ const amountAtomic = BigInt(requirement.amount);
114
+ if (maxUsdcAtomic != null && amountAtomic > maxUsdcAtomic) {
115
+ throw new Error(`402 requires ${amountAtomic} atomic units but maxUsdcAtomic=${maxUsdcAtomic}`);
116
+ }
117
+ // -----------------------------------------------------------------------
118
+ // Step 3: pay via wallet.send()
119
+ // -----------------------------------------------------------------------
120
+ // getWallet(locator, args) loads an existing wallet by address. The
121
+ // WalletArgsFor type omits `recovery`, but the runtime
122
+ // `createWalletInstance` reads it if present — we use that so the
123
+ // returned Wallet has its recovery field populated with the secret,
124
+ // enabling the auto-assembled signer path to succeed without a separate
125
+ // useSigner call.
126
+ const { recoverySecret } = getConfig();
127
+ const wallets = getWalletsClient();
128
+ const wallet = await wallets.getWallet(payerAddress, {
129
+ chain,
130
+ recovery: { type: "server", secret: recoverySecret },
131
+ });
132
+ const tokenSymbol = resolveTokenSymbol(requirement.asset);
133
+ const decimals = typeof requirement.extra?.decimals === "number"
134
+ ? requirement.extra.decimals
135
+ : 6; // USDC default
136
+ const decimalAmount = atomicToDecimal(requirement.amount, decimals);
137
+ console.error(`[payX402Endpoint] paying ${decimalAmount} ${tokenSymbol} to ${requirement.payTo} on ${chain}...`);
138
+ const txResult = await wallet.send(requirement.payTo, tokenSymbol, decimalAmount);
139
+ console.error(`[payX402Endpoint] tx confirmed: ${txResult.hash}`);
140
+ // -----------------------------------------------------------------------
141
+ // Step 4: build X-PAYMENT header + retry
142
+ // -----------------------------------------------------------------------
143
+ const paymentPayload = {
144
+ x402Version: paymentRequired.x402Version,
145
+ accepted: requirement,
146
+ payload: {
147
+ transactionSignature: txResult.hash,
148
+ // Also include under "signature" for compatibility with facilitators
149
+ // that use that field name
150
+ signature: txResult.hash,
151
+ },
152
+ };
153
+ const paymentHeader = Buffer.from(JSON.stringify(paymentPayload)).toString("base64");
154
+ const paidResponse = await fetchWith(url, method, { ...headers, "X-PAYMENT": paymentHeader }, jsonBody);
155
+ if (paidResponse.status < 200 || paidResponse.status >= 300) {
156
+ const body = await safeJson(paidResponse);
157
+ throw new Error(`Paid but endpoint returned ${paidResponse.status}: ${JSON.stringify(body)}`);
158
+ }
159
+ return {
160
+ url,
161
+ transactionSignature: txResult.hash,
162
+ responseStatus: paidResponse.status,
163
+ responseBody: await safeJson(paidResponse),
164
+ explorerLink: txResult.explorerLink || getExplorerLink(txResult.hash, chain),
165
+ };
166
+ }
167
+ // ---------------------------------------------------------------------------
168
+ // Helpers
169
+ // ---------------------------------------------------------------------------
170
+ async function fetchWith(url, method, headers, jsonBody) {
171
+ const init = { method, headers: { ...headers } };
172
+ if (jsonBody !== undefined && method !== "GET" && method !== "HEAD") {
173
+ init.body = JSON.stringify(jsonBody);
174
+ init.headers["Content-Type"] = "application/json";
175
+ }
176
+ return fetch(url, init);
177
+ }
178
+ async function safeJson(res) {
179
+ const text = await res.text();
180
+ if (!text)
181
+ return null;
182
+ try {
183
+ return JSON.parse(text);
184
+ }
185
+ catch {
186
+ return text;
187
+ }
188
+ }
189
+ //# sourceMappingURL=pay-x402-endpoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pay-x402-endpoint.js","sourceRoot":"","sources":["../../src/core/pay-x402-endpoint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { Chain, TransferResult } from "./types.js";
2
+ /**
3
+ * Transfer a token from a Crossmint smart wallet to any recipient address
4
+ * or user locator. This is the general-purpose sibling of payX402Endpoint:
5
+ * same `wallet.send()` primitive underneath, same getWallet + recovery-cast
6
+ * pattern to work around the SDK 1.0.7 useSigner crash, but with no 402
7
+ * protocol handling — just the raw transfer.
8
+ *
9
+ * `token` accepts either a token symbol the SDK recognizes (e.g. "usdc",
10
+ * "sol", "eth") or a raw mint/contract address. `amount` is a decimal
11
+ * string in human units (e.g. "0.01" for 0.01 USDC), not atomic units.
12
+ */
13
+ export declare function transferToken(opts: {
14
+ payerAddress: string;
15
+ chain: Chain;
16
+ to: string;
17
+ token: string;
18
+ amount: string;
19
+ }): Promise<TransferResult>;
20
+ //# sourceMappingURL=transfer-token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transfer-token.d.ts","sourceRoot":"","sources":["../../src/core/transfer-token.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGxD;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,KAAK,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,cAAc,CAAC,CAqB1B"}
@@ -0,0 +1,33 @@
1
+ import { getConfig, getWalletsClient } from "./client.js";
2
+ import { getExplorerLink } from "./create-wallet.js";
3
+ /**
4
+ * Transfer a token from a Crossmint smart wallet to any recipient address
5
+ * or user locator. This is the general-purpose sibling of payX402Endpoint:
6
+ * same `wallet.send()` primitive underneath, same getWallet + recovery-cast
7
+ * pattern to work around the SDK 1.0.7 useSigner crash, but with no 402
8
+ * protocol handling — just the raw transfer.
9
+ *
10
+ * `token` accepts either a token symbol the SDK recognizes (e.g. "usdc",
11
+ * "sol", "eth") or a raw mint/contract address. `amount` is a decimal
12
+ * string in human units (e.g. "0.01" for 0.01 USDC), not atomic units.
13
+ */
14
+ export async function transferToken(opts) {
15
+ const { payerAddress, chain, to, token, amount } = opts;
16
+ const { recoverySecret } = getConfig();
17
+ const wallets = getWalletsClient();
18
+ const wallet = await wallets.getWallet(payerAddress, {
19
+ chain,
20
+ recovery: { type: "server", secret: recoverySecret },
21
+ });
22
+ const tx = await wallet.send(to, token, amount);
23
+ return {
24
+ chain,
25
+ from: payerAddress,
26
+ to,
27
+ token,
28
+ amount,
29
+ transactionSignature: tx.hash,
30
+ explorerLink: tx.explorerLink || getExplorerLink(tx.hash, chain),
31
+ };
32
+ }
33
+ //# sourceMappingURL=transfer-token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transfer-token.js","sourceRoot":"","sources":["../../src/core/transfer-token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAMnC;IACC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAExD,MAAM,EAAE,cAAc,EAAE,GAAG,SAAS,EAAE,CAAC;IACvC,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,YAAY,EAAE;QACnD,KAAK;QACL,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE;KACQ,CAAC,CAAC;IAEhE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAEhD,OAAO;QACL,KAAK;QACL,IAAI,EAAE,YAAY;QAClB,EAAE;QACF,KAAK;QACL,MAAM;QACN,oBAAoB,EAAE,EAAE,CAAC,IAAI;QAC7B,YAAY,EAAE,EAAE,CAAC,YAAY,IAAI,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC;KACjE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Shared types for the core layer. Kept deliberately narrow so the MCP tool
3
+ * schemas (src/mcp/tools.ts) can mirror them without drift.
4
+ */
5
+ /**
6
+ * Chain literals we expose on the MCP surface. These must be a subset of
7
+ * `@crossmint/wallets-sdk`'s `Chain` type. Note that the SDK does NOT expose
8
+ * a `"solana-devnet"` literal — Solana testnet/devnet is selected by the
9
+ * Crossmint API key environment (staging key → devnet, production key →
10
+ * mainnet), not by a separate chain name. EVM chains DO have explicit
11
+ * testnet literals (e.g. "base-sepolia").
12
+ */
13
+ export type Chain = "solana" | "base" | "base-sepolia";
14
+ export interface CreateWalletResult {
15
+ owner: string | null;
16
+ chain: Chain;
17
+ address: string;
18
+ explorerLink: string;
19
+ }
20
+ export interface TokenBalance {
21
+ symbol: string;
22
+ amount: string;
23
+ decimals: number;
24
+ }
25
+ export interface BalanceResult {
26
+ address: string;
27
+ chain: Chain;
28
+ balances: TokenBalance[];
29
+ }
30
+ export interface TransferResult {
31
+ chain: Chain;
32
+ from: string;
33
+ to: string;
34
+ token: string;
35
+ amount: string;
36
+ transactionSignature: string;
37
+ explorerLink: string;
38
+ }
39
+ export interface PayX402Result {
40
+ url: string;
41
+ transactionSignature: string;
42
+ responseStatus: number;
43
+ responseBody: unknown;
44
+ explorerLink: string;
45
+ }
46
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;GAOG;AACH,MAAM,MAAM,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,cAAc,CAAC;AAEvD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB,EAAE,MAAM,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,oBAAoB,EAAE,MAAM,CAAC;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACtB"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Shared types for the core layer. Kept deliberately narrow so the MCP tool
3
+ * schemas (src/mcp/tools.ts) can mirror them without drift.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Library entry point. Re-exports the core primitives so consumers can import
3
+ * from `crossmint-wallets-mcp` directly without reaching into `src/core/`.
4
+ *
5
+ * The MCP server entry point lives at `src/mcp/server.ts` (see the `bin`
6
+ * field in package.json).
7
+ */
8
+ export { createWallet, getExplorerLink } from "./core/create-wallet.js";
9
+ export { getBalance } from "./core/get-balance.js";
10
+ export { transferToken } from "./core/transfer-token.js";
11
+ export { payX402Endpoint } from "./core/pay-x402-endpoint.js";
12
+ export { getConfig, getWalletsClient, resetConfigCache } from "./core/client.js";
13
+ export type { Chain, CreateWalletResult, BalanceResult, TokenBalance, TransferResult, PayX402Result, } from "./core/types.js";
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACjF,YAAY,EACV,KAAK,EACL,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,cAAc,EACd,aAAa,GACd,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Library entry point. Re-exports the core primitives so consumers can import
3
+ * from `crossmint-wallets-mcp` directly without reaching into `src/core/`.
4
+ *
5
+ * The MCP server entry point lives at `src/mcp/server.ts` (see the `bin`
6
+ * field in package.json).
7
+ */
8
+ export { createWallet, getExplorerLink } from "./core/create-wallet.js";
9
+ export { getBalance } from "./core/get-balance.js";
10
+ export { transferToken } from "./core/transfer-token.js";
11
+ export { payX402Endpoint } from "./core/pay-x402-endpoint.js";
12
+ export { getConfig, getWalletsClient, resetConfigCache } from "./core/client.js";
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Standardized error shapes for MCP tool responses.
3
+ *
4
+ * The MCP protocol represents tool failures via `isError: true` plus a
5
+ * human-readable `content` block. We wrap errors in a consistent shape so
6
+ * that clients can display them uniformly and so that smoke tests can match
7
+ * on `error_code` without parsing free-form strings.
8
+ */
9
+ export type CrossmintMcpErrorCode = "CONFIG_MISSING" | "WALLET_NOT_FOUND" | "INSUFFICIENT_BALANCE" | "X402_CHALLENGE_FAILED" | "X402_PAYMENT_REJECTED" | "SDK_ERROR" | "NETWORK_ERROR" | "VALIDATION_ERROR" | "UNKNOWN";
10
+ export interface CrossmintMcpErrorPayload {
11
+ error_code: CrossmintMcpErrorCode;
12
+ message: string;
13
+ hint?: string;
14
+ }
15
+ export declare function toolErrorResponse(code: CrossmintMcpErrorCode, message: string, hint?: string): {
16
+ isError: true;
17
+ content: Array<{
18
+ type: "text";
19
+ text: string;
20
+ }>;
21
+ };
22
+ export declare function classifyError(err: unknown): CrossmintMcpErrorCode;
23
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/mcp/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,qBAAqB,GAC7B,gBAAgB,GAChB,kBAAkB,GAClB,sBAAsB,GACtB,uBAAuB,GACvB,uBAAuB,GACvB,WAAW,GACX,eAAe,GACf,kBAAkB,GAClB,SAAS,CAAC;AAEd,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,qBAAqB,CAAC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,qBAAqB,EAC3B,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,MAAM,GACZ;IACD,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD,CAOA;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,qBAAqB,CAWjE"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Standardized error shapes for MCP tool responses.
3
+ *
4
+ * The MCP protocol represents tool failures via `isError: true` plus a
5
+ * human-readable `content` block. We wrap errors in a consistent shape so
6
+ * that clients can display them uniformly and so that smoke tests can match
7
+ * on `error_code` without parsing free-form strings.
8
+ */
9
+ export function toolErrorResponse(code, message, hint) {
10
+ const payload = { error_code: code, message };
11
+ if (hint)
12
+ payload.hint = hint;
13
+ return {
14
+ isError: true,
15
+ content: [{ type: "text", text: JSON.stringify(payload, null, 2) }],
16
+ };
17
+ }
18
+ export function classifyError(err) {
19
+ if (!(err instanceof Error))
20
+ return "UNKNOWN";
21
+ const msg = err.message.toLowerCase();
22
+ if (msg.includes("env var") || msg.includes("required"))
23
+ return "CONFIG_MISSING";
24
+ if (msg.includes("not found") || msg.includes("does not exist"))
25
+ return "WALLET_NOT_FOUND";
26
+ if (msg.includes("insufficient"))
27
+ return "INSUFFICIENT_BALANCE";
28
+ if (msg.includes("402") || msg.includes("x-payment"))
29
+ return "X402_CHALLENGE_FAILED";
30
+ if (msg.includes("fetch") || msg.includes("network") || msg.includes("econn"))
31
+ return "NETWORK_ERROR";
32
+ return "SDK_ERROR";
33
+ }
34
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/mcp/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAmBH,MAAM,UAAU,iBAAiB,CAC/B,IAA2B,EAC3B,OAAe,EACf,IAAa;IAKb,MAAM,OAAO,GAA6B,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACxE,IAAI,IAAI;QAAE,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAC9B,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;KACpE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAY;IACxC,IAAI,CAAC,CAAC,GAAG,YAAY,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC9C,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;IACtC,IAAI,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,gBAAgB,CAAC;IACjF,IAAI,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QAC7D,OAAO,kBAAkB,CAAC;IAC5B,IAAI,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC;QAAE,OAAO,sBAAsB,CAAC;IAChE,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC;QAAE,OAAO,uBAAuB,CAAC;IACrF,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC;QAC3E,OAAO,eAAe,CAAC;IACzB,OAAO,WAAW,CAAC;AACrB,CAAC"}
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Crossmint Wallets MCP server — stdio transport entry point.
4
+ *
5
+ * IMPORTANT: this process uses stdout as the JSON-RPC transport channel.
6
+ * All human-readable logging MUST go to stderr via `console.error(...)`.
7
+ * Never `console.log` or `process.stdout.write` from anywhere in this
8
+ * server — the MCP client will treat it as malformed protocol traffic.
9
+ *
10
+ * Populated incrementally:
11
+ * - Phase 2B (this file): minimal server that registers zero tools and
12
+ * connects the stdio transport. Proves the pipeline works.
13
+ * - Phase 2E: real tool registration via `registerTools` in ./tools.ts.
14
+ */
15
+ export {};
16
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;GAYG"}
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Crossmint Wallets MCP server — stdio transport entry point.
4
+ *
5
+ * IMPORTANT: this process uses stdout as the JSON-RPC transport channel.
6
+ * All human-readable logging MUST go to stderr via `console.error(...)`.
7
+ * Never `console.log` or `process.stdout.write` from anywhere in this
8
+ * server — the MCP client will treat it as malformed protocol traffic.
9
+ *
10
+ * Populated incrementally:
11
+ * - Phase 2B (this file): minimal server that registers zero tools and
12
+ * connects the stdio transport. Proves the pipeline works.
13
+ * - Phase 2E: real tool registration via `registerTools` in ./tools.ts.
14
+ */
15
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
16
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
17
+ import { registerTools } from "./tools.js";
18
+ const SERVER_NAME = "crossmint-wallets-mcp";
19
+ const SERVER_VERSION = "0.1.0";
20
+ async function main() {
21
+ const server = new McpServer({
22
+ name: SERVER_NAME,
23
+ version: SERVER_VERSION,
24
+ });
25
+ registerTools(server);
26
+ const transport = new StdioServerTransport();
27
+ await server.connect(transport);
28
+ console.error(`[${SERVER_NAME}] v${SERVER_VERSION} connected via stdio transport`);
29
+ }
30
+ main().catch((err) => {
31
+ console.error(`[${SERVER_NAME}] fatal:`, err);
32
+ process.exit(1);
33
+ });
34
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,WAAW,GAAG,uBAAuB,CAAC;AAC5C,MAAM,cAAc,GAAG,OAAO,CAAC;AAE/B,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,cAAc;KACxB,CAAC,CAAC;IAEH,aAAa,CAAC,MAAM,CAAC,CAAC;IAEtB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,OAAO,CAAC,KAAK,CACX,IAAI,WAAW,MAAM,cAAc,gCAAgC,CACpE,CAAC;AACJ,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,IAAI,WAAW,UAAU,EAAE,GAAG,CAAC,CAAC;IAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerTools(server: McpServer): void;
3
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA0CzE,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwMrD"}