@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.
- package/dist/core/config.d.ts +1 -1
- package/dist/core/payments.js +13 -1
- package/dist/index.js +29 -27
- package/dist/tools/passes.js +3 -2
- package/dist/tools/run.js +3 -2
- package/dist/tools/solve.js +3 -2
- package/dist/tools/wallet.js +79 -7
- package/package.json +2 -7
- package/src/core/config.ts +2 -2
- package/src/core/payments.ts +11 -1
- package/src/index.ts +29 -27
- package/src/tools/passes.ts +3 -2
- package/src/tools/run.ts +3 -2
- package/src/tools/solve.ts +3 -2
- package/src/tools/wallet.ts +84 -9
package/dist/core/config.d.ts
CHANGED
package/dist/core/payments.js
CHANGED
|
@@ -368,7 +368,19 @@ export async function getWalletAddress(method) {
|
|
|
368
368
|
}
|
|
369
369
|
}
|
|
370
370
|
if (chain === "solana") {
|
|
371
|
-
|
|
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,
|
|
27
|
+
"Agent Wonderland — on-demand AI agent marketplace with autonomous per-call payment. Discover, run, rate.",
|
|
28
28
|
"",
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
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.
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"4.
|
|
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
|
-
"-
|
|
43
|
-
"-
|
|
44
|
-
"-
|
|
45
|
-
"
|
|
46
|
-
"-
|
|
47
|
-
"-
|
|
48
|
-
"-
|
|
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
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
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
|
|
60
|
-
"
|
|
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
|
package/dist/tools/passes.js
CHANGED
|
@@ -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
|
|
56
|
-
"
|
|
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
|
|
82
|
-
"
|
|
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.");
|
package/dist/tools/solve.js
CHANGED
|
@@ -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
|
|
131
|
-
"
|
|
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.");
|
package/dist/tools/wallet.js
CHANGED
|
@@ -190,11 +190,55 @@ export function registerWalletTools(server) {
|
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
192
|
if (!owsReady) {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
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
|
-
|
|
248
|
-
|
|
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.
|
|
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
|
-
"
|
|
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",
|
package/src/core/config.ts
CHANGED
|
@@ -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
|
|
10
|
-
key?: string; // private key (
|
|
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
|
package/src/core/payments.ts
CHANGED
|
@@ -417,7 +417,17 @@ export async function getWalletAddress(method?: string): Promise<string | null>
|
|
|
417
417
|
}
|
|
418
418
|
|
|
419
419
|
if (chain === "solana") {
|
|
420
|
-
|
|
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,
|
|
34
|
+
"Agent Wonderland — on-demand AI agent marketplace with autonomous per-call payment. Discover, run, rate.",
|
|
35
35
|
"",
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
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.
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"4.
|
|
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
|
-
"-
|
|
50
|
-
"-
|
|
51
|
-
"-
|
|
52
|
-
"
|
|
53
|
-
"-
|
|
54
|
-
"-
|
|
55
|
-
"-
|
|
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
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
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
|
|
67
|
-
"
|
|
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
|
);
|
package/src/tools/passes.ts
CHANGED
|
@@ -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
|
|
88
|
-
"
|
|
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
|
|
123
|
-
"
|
|
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.");
|
package/src/tools/solve.ts
CHANGED
|
@@ -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
|
|
166
|
-
"
|
|
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.");
|
package/src/tools/wallet.ts
CHANGED
|
@@ -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
|
-
|
|
250
|
-
"
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
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
|
-
|
|
316
|
-
|
|
317
|
-
|
|
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
|