@agentwonderland/mcp 0.1.27 → 0.1.29

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.
@@ -1,6 +1,6 @@
1
1
  export interface WalletEntry {
2
2
  id: string;
3
- keyType: "evm" | "ows";
3
+ keyType: "evm" | "solana" | "ows";
4
4
  key?: string;
5
5
  owsWalletId?: string;
6
6
  chains: string[];
@@ -368,7 +368,19 @@ export async function getWalletAddress(method) {
368
368
  }
369
369
  }
370
370
  if (chain === "solana") {
371
- return null;
371
+ // Raw Solana ed25519 key path (plaintext fallback when OWS is unavailable)
372
+ if (!wallet.key)
373
+ return null;
374
+ try {
375
+ const { Keypair } = await import("@solana/web3.js");
376
+ const hex = wallet.key.startsWith("0x") ? wallet.key.slice(2) : wallet.key;
377
+ const bytes = Uint8Array.from(Buffer.from(hex, "hex"));
378
+ const kp = bytes.length === 32 ? Keypair.fromSeed(bytes) : Keypair.fromSecretKey(bytes);
379
+ return kp.publicKey.toBase58();
380
+ }
381
+ catch {
382
+ return null;
383
+ }
372
384
  }
373
385
  // Raw EVM key path
374
386
  if (!wallet.key)
package/dist/index.js CHANGED
@@ -24,40 +24,42 @@ export async function startMcpServer() {
24
24
  version: "0.2.0",
25
25
  }, {
26
26
  instructions: [
27
- "Agent Wonderland — AI agent marketplace. Discover, run, and rate agents.",
27
+ "Agent Wonderland — on-demand AI agent marketplace with autonomous per-call payment. Discover, run, rate.",
28
28
  "",
29
- "FILE HANDLING:",
30
- "Pass local file paths directly as input values (e.g. image: \"/path/to/photo.jpg\").",
31
- "The MCP auto-uploads to cloud storage and replaces with a URL. Never base64-encode.",
29
+ "PURPOSE:",
30
+ "You are an AI agent calling this MCP to extend your capabilities. Instead of integrating N APIs with N keys,",
31
+ "you pay specialist agents per call in USDC. This works headlessly in automations (n8n, cron) and interactively",
32
+ "(Claude Code, Desktop). Favor one-shot `solve()` for autonomous use; prefer `search_agents()` + `run_agent()`",
33
+ "when the caller wants to pick a specific agent.",
32
34
  "",
33
35
  "WORKFLOW:",
34
- "1. search_agents() or solve() — find agents for the task",
35
- "2. get_agent() check required input fields before running",
36
- "3. run_agent() or solve() with ALL required fields",
37
- "3a. If the agent offers discounted credit packs, use buy_agent_credit_pack() and list_agent_credit_packs() when helpful",
38
- "4. If no payment method is set up, run_agent returns a setup page to connect a credit card present it to the user",
39
- "5. Ask user to rate or tip after a successful run",
36
+ "1. solve(intent, input, budget) — one call: find best agent + pay + run. Use when the task is clear.",
37
+ " OR: search_agents() → get_agent() to inspect schema run_agent() with required fields.",
38
+ "2. If the agent returns status 'processing', poll with get_job(). Async runs resolve automatically.",
39
+ "3. After a successful run, rate_agent() and optionally tip_agent() if the result was useful.",
40
+ "4. Use list_jobs() to recover state across sessions (it checks every configured wallet).",
40
41
  "",
41
- "PAYMENT:",
42
- "- Crypto wallets (Tempo USDC, Base USDC, Solana USDC) are the core supported rails.",
43
- "- Saved cards can also be used, but card-backed MPP depends on Stripe Shared Payment Token availability in the current environment.",
44
- "- Card and crypto are SEPARATE payment methods. Card charges a credit card; crypto sends USDC on-chain.",
45
- "- When a card is configured, it becomes the default payment method. Use wallet_status to confirm whether `Card MPP: ready` before relying on it.",
46
- "- run_agent() and solve() auto-detect the default compatible payment method when pay_with is omitted.",
47
- "- Include pay_with explicitly when you need a specific rail or want deterministic control over the payment method used.",
48
- "- Use wallet_status to see the exact payment methods the user has configured before calling a paid tool.",
49
- "- Payment is automatic once configured. Users are never charged for failed runs.",
50
- "- Do NOT ask the user to set up payment before they try to run an agent. Let them explore freely.",
51
- "- If a specific payment method fails, report the error clearly. Do NOT silently fall back to a different method.",
52
- "- When payment fails, suggest alternatives using wallet_status.",
42
+ "PAYMENT (crypto-only right now):",
43
+ "- Supported rails: Tempo USDC, Base USDC, Solana USDC. Card is temporarily disabled pending Stripe SPT approval.",
44
+ "- Tempo and Base share one EVM wallet key. Solana uses a separate ed25519 key. One OWS wallet can manage both.",
45
+ "- If pay_with is omitted, the MCP auto-selects a compatible configured rail. Pass pay_with explicitly",
46
+ " (tempo | base | solana | wallet-id) for deterministic behavior.",
47
+ "- Payment is automatic: on a 402 challenge the MCP signs on-chain, submits, then retries. Failed runs are refunded.",
48
+ "- If a specific rail fails, surface the real reason do NOT silently retry with a different method.",
49
+ "- Headless/automation: set wallet_set_policy() to cap max_per_tx and max_per_day so a runaway loop can't drain funds.",
53
50
  "",
54
- "MANAGING PAYMENT METHODS:",
55
- "- To remove a card: wallet_setup({ action: \"remove-card\" })",
56
- "- To remove or modify a crypto wallet: NEVER do this programmatically. Direct users to edit their config files manually (~/.agentwonderland/config.json or ~/.ows/). We do not handle private key deletion or modification to avoid any risk of key loss.",
51
+ "FILE HANDLING:",
52
+ "Pass local file paths directly as input values (e.g. image: \"/path/to/photo.jpg\"). The MCP auto-uploads to",
53
+ "cloud storage and replaces with a URL before sending to the agent. Never base64-encode.",
57
54
  "",
58
55
  "REQUIRED FIELDS:",
59
- "Always check the agent's input schema (via get_agent) before calling run_agent.",
60
- "Include ALL required fields in the first attempt to avoid validation errors.",
56
+ "Always inspect the agent's input schema via get_agent() before calling run_agent(). Include ALL required",
57
+ "fields in the first attempt validation errors cost a round trip.",
58
+ "",
59
+ "WALLET HYGIENE:",
60
+ "- wallet_status shows per-chain USDC balance and the active network (mainnet vs testnet).",
61
+ "- To create or import a crypto wallet: wallet_setup({ action: \"create\" }) or { action: \"import\", key }.",
62
+ "- NEVER delete or rotate keys programmatically. Direct users to edit ~/.agentwonderland/config.json or ~/.ows/ manually.",
61
63
  ].join("\n"),
62
64
  });
63
65
  // Register tools
@@ -52,8 +52,9 @@ export function registerPassTools(server) {
52
52
  "No payment method configured.",
53
53
  "",
54
54
  "Supported rails: Tempo USDC, Base USDC, Solana USDC.",
55
- "Run wallet_setup({ action: \"create\" }) to create a crypto wallet,",
56
- "or wallet_setup({ action: \"import\" }) with an existing key.",
55
+ "Run wallet_setup({ action: \"create\" }) to create a wallet (falls back to plaintext storage",
56
+ "if OWS is not installed install @open-wallet-standard/core globally for encrypted keys).",
57
+ "Or wallet_setup({ action: \"import\", key: \"<hex>\" }) with an existing key.",
57
58
  ];
58
59
  if (isCardPaymentEnabled()) {
59
60
  setupLines.push("", "Or wallet_setup({ action: \"add-card\" }) to connect a credit card.");
package/dist/tools/run.js CHANGED
@@ -78,8 +78,9 @@ export function registerRunTools(server) {
78
78
  "No payment method configured.",
79
79
  "",
80
80
  "Supported rails: Tempo USDC, Base USDC, Solana USDC.",
81
- "Run wallet_setup({ action: \"create\" }) to create a crypto wallet,",
82
- "or wallet_setup({ action: \"import\" }) with an existing key.",
81
+ "Run wallet_setup({ action: \"create\" }) to create a wallet (falls back to plaintext storage",
82
+ "if OWS is not installed install @open-wallet-standard/core globally for encrypted keys).",
83
+ "Or wallet_setup({ action: \"import\", key: \"<hex>\" }) with an existing key.",
83
84
  ];
84
85
  if (isCardPaymentEnabled()) {
85
86
  setupLines.push("", "Or wallet_setup({ action: \"add-card\" }) to connect a credit card.");
@@ -127,8 +127,9 @@ export function registerSolveTools(server) {
127
127
  "No payment method configured.",
128
128
  "",
129
129
  "Supported rails: Tempo USDC, Base USDC, Solana USDC.",
130
- "Run wallet_setup({ action: \"create\" }) to create a crypto wallet,",
131
- "or wallet_setup({ action: \"import\" }) with an existing key.",
130
+ "Run wallet_setup({ action: \"create\" }) to create a wallet (falls back to plaintext storage",
131
+ "if OWS is not installed install @open-wallet-standard/core globally for encrypted keys).",
132
+ "Or wallet_setup({ action: \"import\", key: \"<hex>\" }) with an existing key.",
132
133
  ];
133
134
  if (isCardPaymentEnabled()) {
134
135
  setupLines.push("", "Or wallet_setup({ action: \"add-card\" }) to connect a credit card.");
@@ -190,11 +190,55 @@ export function registerWalletTools(server) {
190
190
  }
191
191
  }
192
192
  if (!owsReady) {
193
- return text("Cannot create wallet: OWS (Open Wallet Standard) is not installed.\n" +
194
- "Install with: npm install -g @open-wallet-standard/core\n\n" +
195
- (defaultCh === "solana"
196
- ? "Solana wallets currently require OWS-managed encrypted storage."
197
- : "Alternatively, use action 'import' with an existing private key."));
193
+ // Fallback: generate a plaintext wallet stored in ~/.agentwonderland/config.json.
194
+ // Safe for prototyping; install OWS for encrypted at-rest storage.
195
+ const walletName = name ?? `aw-${Date.now()}`;
196
+ if (preferredOwsChain === "solana") {
197
+ const { Keypair } = await import("@solana/web3.js");
198
+ const kp = Keypair.generate();
199
+ const secretHex = Buffer.from(kp.secretKey).toString("hex");
200
+ addWallet({
201
+ id: walletName,
202
+ keyType: "solana",
203
+ key: secretHex,
204
+ chains: ["solana"],
205
+ defaultChain: "solana",
206
+ label: walletName,
207
+ });
208
+ const principal = await ensureConsumerPrincipal();
209
+ return text([
210
+ "Wallet created [plaintext — install OWS for encrypted storage]:",
211
+ ` Address: ${kp.publicKey.toBase58()}`,
212
+ ` Name: ${walletName}`,
213
+ ` Chains: solana`,
214
+ ` Consumer principal: ${principal}`,
215
+ "",
216
+ "Fund this address with USDC on Solana to start using agents.",
217
+ "For encrypted storage, install OWS: npm install -g @open-wallet-standard/core",
218
+ ].join("\n"));
219
+ }
220
+ const { generatePrivateKey, privateKeyToAccount } = await import("viem/accounts");
221
+ const privateKey = generatePrivateKey();
222
+ const account = privateKeyToAccount(privateKey);
223
+ addWallet({
224
+ id: walletName,
225
+ keyType: "evm",
226
+ key: privateKey,
227
+ chains: ["tempo", "base"],
228
+ defaultChain: defaultCh === "solana" ? "tempo" : defaultCh,
229
+ label: walletName,
230
+ });
231
+ const principal = await ensureConsumerPrincipal();
232
+ return text([
233
+ "Wallet created [plaintext — install OWS for encrypted storage]:",
234
+ ` Address: ${account.address}`,
235
+ ` Name: ${walletName}`,
236
+ ` Chains: tempo, base`,
237
+ ` Consumer principal: ${principal}`,
238
+ "",
239
+ `Fund this address with USDC on Tempo or Base to start using agents.`,
240
+ "For encrypted storage, install OWS: npm install -g @open-wallet-standard/core",
241
+ ].join("\n"));
198
242
  }
199
243
  const walletName = name ?? `aw-${Date.now()}`;
200
244
  const result = await createOwsWallet(walletName, preferredOwsChain);
@@ -244,8 +288,36 @@ export function registerWalletTools(server) {
244
288
  ].join("\n"));
245
289
  }
246
290
  if (defaultCh === "solana") {
247
- return text("Solana key import currently requires OWS (Open Wallet Standard) so the ed25519 key can be stored safely.\n" +
248
- "Install with: npm install -g @open-wallet-standard/core");
291
+ // Plaintext Solana import fallback.
292
+ try {
293
+ const { Keypair } = await import("@solana/web3.js");
294
+ const raw = key.startsWith("0x") ? key.slice(2) : key;
295
+ const bytes = Uint8Array.from(Buffer.from(raw, "hex"));
296
+ const kp = bytes.length === 32 ? Keypair.fromSeed(bytes) : Keypair.fromSecretKey(bytes);
297
+ const walletName = name ?? `imported-${Date.now()}`;
298
+ addWallet({
299
+ id: walletName,
300
+ keyType: "solana",
301
+ key: raw,
302
+ chains: ["solana"],
303
+ defaultChain: "solana",
304
+ label: walletName,
305
+ });
306
+ const principal = await ensureConsumerPrincipal();
307
+ return text([
308
+ "Key imported [plaintext — install OWS for encrypted storage]:",
309
+ ` Address: ${kp.publicKey.toBase58()}`,
310
+ ` Name: ${walletName}`,
311
+ ` Chains: solana`,
312
+ ` Consumer principal: ${principal}`,
313
+ "",
314
+ "For encrypted storage, install OWS: npm install -g @open-wallet-standard/core",
315
+ ].join("\n"));
316
+ }
317
+ catch (err) {
318
+ return text(`Invalid Solana key: ${err instanceof Error ? err.message : String(err)}\n` +
319
+ "Expected a 32-byte seed or 64-byte secret key, hex-encoded.");
320
+ }
249
321
  }
250
322
  // No OWS — store plaintext
251
323
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentwonderland/mcp",
3
- "version": "0.1.27",
3
+ "version": "0.1.29",
4
4
  "type": "module",
5
5
  "description": "MCP server for the Agent Wonderland AI agent marketplace",
6
6
  "bin": {
@@ -30,14 +30,9 @@
30
30
  "viem": "^2.47.6",
31
31
  "zod": "^3.24.0"
32
32
  },
33
- "peerDependencies": {
33
+ "optionalDependencies": {
34
34
  "@open-wallet-standard/core": "^1.0.0"
35
35
  },
36
- "peerDependenciesMeta": {
37
- "@open-wallet-standard/core": {
38
- "optional": true
39
- }
40
- },
41
36
  "devDependencies": {
42
37
  "@types/qrcode": "^1.5.6",
43
38
  "tsx": "^4.0.0",
@@ -6,8 +6,8 @@ import { homedir } from "node:os";
6
6
 
7
7
  export interface WalletEntry {
8
8
  id: string; // e.g. "evm-1"
9
- keyType: "evm" | "ows"; // key format: raw EVM key or OWS-managed wallet
10
- key?: string; // private key (legacy / raw EVM only)
9
+ keyType: "evm" | "solana" | "ows"; // key format: raw EVM / raw Solana / OWS-managed
10
+ key?: string; // private key hex (secp256k1 for evm, ed25519 for solana)
11
11
  owsWalletId?: string; // OWS wallet reference (when keyType === "ows")
12
12
  chains: string[]; // enabled chains: "tempo", "base", "solana"
13
13
  defaultChain?: string; // which chain to use by default for this wallet
@@ -417,7 +417,17 @@ export async function getWalletAddress(method?: string): Promise<string | null>
417
417
  }
418
418
 
419
419
  if (chain === "solana") {
420
- return null;
420
+ // Raw Solana ed25519 key path (plaintext fallback when OWS is unavailable)
421
+ if (!wallet.key) return null;
422
+ try {
423
+ const { Keypair } = await import("@solana/web3.js");
424
+ const hex = wallet.key.startsWith("0x") ? wallet.key.slice(2) : wallet.key;
425
+ const bytes = Uint8Array.from(Buffer.from(hex, "hex"));
426
+ const kp = bytes.length === 32 ? Keypair.fromSeed(bytes) : Keypair.fromSecretKey(bytes);
427
+ return kp.publicKey.toBase58();
428
+ } catch {
429
+ return null;
430
+ }
421
431
  }
422
432
 
423
433
  // Raw EVM key path
package/src/index.ts CHANGED
@@ -31,40 +31,42 @@ export async function startMcpServer(): Promise<void> {
31
31
  },
32
32
  {
33
33
  instructions: [
34
- "Agent Wonderland — AI agent marketplace. Discover, run, and rate agents.",
34
+ "Agent Wonderland — on-demand AI agent marketplace with autonomous per-call payment. Discover, run, rate.",
35
35
  "",
36
- "FILE HANDLING:",
37
- "Pass local file paths directly as input values (e.g. image: \"/path/to/photo.jpg\").",
38
- "The MCP auto-uploads to cloud storage and replaces with a URL. Never base64-encode.",
36
+ "PURPOSE:",
37
+ "You are an AI agent calling this MCP to extend your capabilities. Instead of integrating N APIs with N keys,",
38
+ "you pay specialist agents per call in USDC. This works headlessly in automations (n8n, cron) and interactively",
39
+ "(Claude Code, Desktop). Favor one-shot `solve()` for autonomous use; prefer `search_agents()` + `run_agent()`",
40
+ "when the caller wants to pick a specific agent.",
39
41
  "",
40
42
  "WORKFLOW:",
41
- "1. search_agents() or solve() — find agents for the task",
42
- "2. get_agent() check required input fields before running",
43
- "3. run_agent() or solve() with ALL required fields",
44
- "3a. If the agent offers discounted credit packs, use buy_agent_credit_pack() and list_agent_credit_packs() when helpful",
45
- "4. If no payment method is set up, run_agent returns a setup page to connect a credit card present it to the user",
46
- "5. Ask user to rate or tip after a successful run",
43
+ "1. solve(intent, input, budget) — one call: find best agent + pay + run. Use when the task is clear.",
44
+ " OR: search_agents() → get_agent() to inspect schema run_agent() with required fields.",
45
+ "2. If the agent returns status 'processing', poll with get_job(). Async runs resolve automatically.",
46
+ "3. After a successful run, rate_agent() and optionally tip_agent() if the result was useful.",
47
+ "4. Use list_jobs() to recover state across sessions (it checks every configured wallet).",
47
48
  "",
48
- "PAYMENT:",
49
- "- Crypto wallets (Tempo USDC, Base USDC, Solana USDC) are the core supported rails.",
50
- "- Saved cards can also be used, but card-backed MPP depends on Stripe Shared Payment Token availability in the current environment.",
51
- "- Card and crypto are SEPARATE payment methods. Card charges a credit card; crypto sends USDC on-chain.",
52
- "- When a card is configured, it becomes the default payment method. Use wallet_status to confirm whether `Card MPP: ready` before relying on it.",
53
- "- run_agent() and solve() auto-detect the default compatible payment method when pay_with is omitted.",
54
- "- Include pay_with explicitly when you need a specific rail or want deterministic control over the payment method used.",
55
- "- Use wallet_status to see the exact payment methods the user has configured before calling a paid tool.",
56
- "- Payment is automatic once configured. Users are never charged for failed runs.",
57
- "- Do NOT ask the user to set up payment before they try to run an agent. Let them explore freely.",
58
- "- If a specific payment method fails, report the error clearly. Do NOT silently fall back to a different method.",
59
- "- When payment fails, suggest alternatives using wallet_status.",
49
+ "PAYMENT (crypto-only right now):",
50
+ "- Supported rails: Tempo USDC, Base USDC, Solana USDC. Card is temporarily disabled pending Stripe SPT approval.",
51
+ "- Tempo and Base share one EVM wallet key. Solana uses a separate ed25519 key. One OWS wallet can manage both.",
52
+ "- If pay_with is omitted, the MCP auto-selects a compatible configured rail. Pass pay_with explicitly",
53
+ " (tempo | base | solana | wallet-id) for deterministic behavior.",
54
+ "- Payment is automatic: on a 402 challenge the MCP signs on-chain, submits, then retries. Failed runs are refunded.",
55
+ "- If a specific rail fails, surface the real reason do NOT silently retry with a different method.",
56
+ "- Headless/automation: set wallet_set_policy() to cap max_per_tx and max_per_day so a runaway loop can't drain funds.",
60
57
  "",
61
- "MANAGING PAYMENT METHODS:",
62
- "- To remove a card: wallet_setup({ action: \"remove-card\" })",
63
- "- To remove or modify a crypto wallet: NEVER do this programmatically. Direct users to edit their config files manually (~/.agentwonderland/config.json or ~/.ows/). We do not handle private key deletion or modification to avoid any risk of key loss.",
58
+ "FILE HANDLING:",
59
+ "Pass local file paths directly as input values (e.g. image: \"/path/to/photo.jpg\"). The MCP auto-uploads to",
60
+ "cloud storage and replaces with a URL before sending to the agent. Never base64-encode.",
64
61
  "",
65
62
  "REQUIRED FIELDS:",
66
- "Always check the agent's input schema (via get_agent) before calling run_agent.",
67
- "Include ALL required fields in the first attempt to avoid validation errors.",
63
+ "Always inspect the agent's input schema via get_agent() before calling run_agent(). Include ALL required",
64
+ "fields in the first attempt validation errors cost a round trip.",
65
+ "",
66
+ "WALLET HYGIENE:",
67
+ "- wallet_status shows per-chain USDC balance and the active network (mainnet vs testnet).",
68
+ "- To create or import a crypto wallet: wallet_setup({ action: \"create\" }) or { action: \"import\", key }.",
69
+ "- NEVER delete or rotate keys programmatically. Direct users to edit ~/.agentwonderland/config.json or ~/.ows/ manually.",
68
70
  ].join("\n"),
69
71
  },
70
72
  );
@@ -84,8 +84,9 @@ export function registerPassTools(server: McpServer): void {
84
84
  "No payment method configured.",
85
85
  "",
86
86
  "Supported rails: Tempo USDC, Base USDC, Solana USDC.",
87
- "Run wallet_setup({ action: \"create\" }) to create a crypto wallet,",
88
- "or wallet_setup({ action: \"import\" }) with an existing key.",
87
+ "Run wallet_setup({ action: \"create\" }) to create a wallet (falls back to plaintext storage",
88
+ "if OWS is not installed install @open-wallet-standard/core globally for encrypted keys).",
89
+ "Or wallet_setup({ action: \"import\", key: \"<hex>\" }) with an existing key.",
89
90
  ];
90
91
  if (isCardPaymentEnabled()) {
91
92
  setupLines.push("", "Or wallet_setup({ action: \"add-card\" }) to connect a credit card.");
package/src/tools/run.ts CHANGED
@@ -119,8 +119,9 @@ export function registerRunTools(server: McpServer): void {
119
119
  "No payment method configured.",
120
120
  "",
121
121
  "Supported rails: Tempo USDC, Base USDC, Solana USDC.",
122
- "Run wallet_setup({ action: \"create\" }) to create a crypto wallet,",
123
- "or wallet_setup({ action: \"import\" }) with an existing key.",
122
+ "Run wallet_setup({ action: \"create\" }) to create a wallet (falls back to plaintext storage",
123
+ "if OWS is not installed install @open-wallet-standard/core globally for encrypted keys).",
124
+ "Or wallet_setup({ action: \"import\", key: \"<hex>\" }) with an existing key.",
124
125
  ];
125
126
  if (isCardPaymentEnabled()) {
126
127
  setupLines.push("", "Or wallet_setup({ action: \"add-card\" }) to connect a credit card.");
@@ -162,8 +162,9 @@ export function registerSolveTools(server: McpServer): void {
162
162
  "No payment method configured.",
163
163
  "",
164
164
  "Supported rails: Tempo USDC, Base USDC, Solana USDC.",
165
- "Run wallet_setup({ action: \"create\" }) to create a crypto wallet,",
166
- "or wallet_setup({ action: \"import\" }) with an existing key.",
165
+ "Run wallet_setup({ action: \"create\" }) to create a wallet (falls back to plaintext storage",
166
+ "if OWS is not installed install @open-wallet-standard/core globally for encrypted keys).",
167
+ "Or wallet_setup({ action: \"import\", key: \"<hex>\" }) with an existing key.",
167
168
  ];
168
169
  if (isCardPaymentEnabled()) {
169
170
  setupLines.push("", "Or wallet_setup({ action: \"add-card\" }) to connect a credit card.");
@@ -245,12 +245,58 @@ export function registerWalletTools(server: McpServer): void {
245
245
  }
246
246
 
247
247
  if (!owsReady) {
248
+ // Fallback: generate a plaintext wallet stored in ~/.agentwonderland/config.json.
249
+ // Safe for prototyping; install OWS for encrypted at-rest storage.
250
+ const walletName = name ?? `aw-${Date.now()}`;
251
+ if (preferredOwsChain === "solana") {
252
+ const { Keypair } = await import("@solana/web3.js");
253
+ const kp = Keypair.generate();
254
+ const secretHex = Buffer.from(kp.secretKey).toString("hex");
255
+ addWallet({
256
+ id: walletName,
257
+ keyType: "solana",
258
+ key: secretHex,
259
+ chains: ["solana"],
260
+ defaultChain: "solana",
261
+ label: walletName,
262
+ });
263
+ const principal = await ensureConsumerPrincipal();
264
+ return text(
265
+ [
266
+ "Wallet created [plaintext — install OWS for encrypted storage]:",
267
+ ` Address: ${kp.publicKey.toBase58()}`,
268
+ ` Name: ${walletName}`,
269
+ ` Chains: solana`,
270
+ ` Consumer principal: ${principal}`,
271
+ "",
272
+ "Fund this address with USDC on Solana to start using agents.",
273
+ "For encrypted storage, install OWS: npm install -g @open-wallet-standard/core",
274
+ ].join("\n"),
275
+ );
276
+ }
277
+ const { generatePrivateKey, privateKeyToAccount } = await import("viem/accounts");
278
+ const privateKey = generatePrivateKey();
279
+ const account = privateKeyToAccount(privateKey);
280
+ addWallet({
281
+ id: walletName,
282
+ keyType: "evm",
283
+ key: privateKey,
284
+ chains: ["tempo", "base"],
285
+ defaultChain: defaultCh === "solana" ? "tempo" : defaultCh,
286
+ label: walletName,
287
+ });
288
+ const principal = await ensureConsumerPrincipal();
248
289
  return text(
249
- "Cannot create wallet: OWS (Open Wallet Standard) is not installed.\n" +
250
- "Install with: npm install -g @open-wallet-standard/core\n\n" +
251
- (defaultCh === "solana"
252
- ? "Solana wallets currently require OWS-managed encrypted storage."
253
- : "Alternatively, use action 'import' with an existing private key."),
290
+ [
291
+ "Wallet created [plaintext install OWS for encrypted storage]:",
292
+ ` Address: ${account.address}`,
293
+ ` Name: ${walletName}`,
294
+ ` Chains: tempo, base`,
295
+ ` Consumer principal: ${principal}`,
296
+ "",
297
+ `Fund this address with USDC on Tempo or Base to start using agents.`,
298
+ "For encrypted storage, install OWS: npm install -g @open-wallet-standard/core",
299
+ ].join("\n"),
254
300
  );
255
301
  }
256
302
 
@@ -312,10 +358,39 @@ export function registerWalletTools(server: McpServer): void {
312
358
  }
313
359
 
314
360
  if (defaultCh === "solana") {
315
- return text(
316
- "Solana key import currently requires OWS (Open Wallet Standard) so the ed25519 key can be stored safely.\n" +
317
- "Install with: npm install -g @open-wallet-standard/core",
318
- );
361
+ // Plaintext Solana import fallback.
362
+ try {
363
+ const { Keypair } = await import("@solana/web3.js");
364
+ const raw = key!.startsWith("0x") ? key!.slice(2) : key!;
365
+ const bytes = Uint8Array.from(Buffer.from(raw, "hex"));
366
+ const kp = bytes.length === 32 ? Keypair.fromSeed(bytes) : Keypair.fromSecretKey(bytes);
367
+ const walletName = name ?? `imported-${Date.now()}`;
368
+ addWallet({
369
+ id: walletName,
370
+ keyType: "solana",
371
+ key: raw,
372
+ chains: ["solana"],
373
+ defaultChain: "solana",
374
+ label: walletName,
375
+ });
376
+ const principal = await ensureConsumerPrincipal();
377
+ return text(
378
+ [
379
+ "Key imported [plaintext — install OWS for encrypted storage]:",
380
+ ` Address: ${kp.publicKey.toBase58()}`,
381
+ ` Name: ${walletName}`,
382
+ ` Chains: solana`,
383
+ ` Consumer principal: ${principal}`,
384
+ "",
385
+ "For encrypted storage, install OWS: npm install -g @open-wallet-standard/core",
386
+ ].join("\n"),
387
+ );
388
+ } catch (err) {
389
+ return text(
390
+ `Invalid Solana key: ${err instanceof Error ? err.message : String(err)}\n` +
391
+ "Expected a 32-byte seed or 64-byte secret key, hex-encoded.",
392
+ );
393
+ }
319
394
  }
320
395
 
321
396
  // No OWS — store plaintext