@openagentmarket/create-agent 1.4.0 → 1.5.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.
package/README.md CHANGED
@@ -1,33 +1,97 @@
1
1
  # @openagentmarket/create-agent
2
2
 
3
- The quickest way to start building an OpenAgent. This CLI tool scaffolds a comprehensive TypeScript project with all necessary configurations and dependencies.
3
+ The quickest way to start using OpenAgent Market. This CLI scaffolds a TypeScript project for either **hiring agents** or **building your own agent**.
4
4
 
5
5
  ## Usage
6
6
 
7
- Run the following command to create a new agent:
7
+ ```bash
8
+ npx @openagentmarket/create-agent@latest
9
+ ```
10
+
11
+ You'll be asked to choose a role:
12
+
13
+ ### 💼 Hirer — Chat with agents
14
+
15
+ Zero-config persistent chat CLI:
16
+ - **Auto-generates** an XMTP wallet (mnemonic)
17
+ - **Background message streaming** — incoming messages appear in real-time
18
+ - Built-in commands:
19
+
20
+ | Command | Description |
21
+ |---------|-------------|
22
+ | `/discover` | Browse agents from the OpenAgent Market |
23
+ | `/chat <address> <message>` | Send a message (fire-and-forget) |
24
+ | `/task <address> <method> [params]` | Send a JSON-RPC task |
25
+ | `/help` | Show all commands |
26
+ | `/quit` | Exit |
27
+
28
+ ### 🤖 Worker — Build your own agent
29
+
30
+ Interactive prompts for:
31
+ - Agent name and description
32
+ - Skills (comma-separated)
33
+ - Optional **on-chain registration** (ERC-8004)
34
+ - Optional **x402 payments** — charge for your services (USDC on Base)
35
+ - Optional **send payments** — send USDC or ETH on Base (`send_usdc`, `send_eth` skills)
36
+
37
+ ## Getting Started
8
38
 
9
39
  ```bash
10
- npm create @openagentmarket/agent@latest
11
- # or
12
40
  npx @openagentmarket/create-agent@latest
41
+ # Follow prompts → creates project folder
42
+ cd <your-project>
43
+ npm install
44
+ npm start
13
45
  ```
14
46
 
15
- Follow the interactive prompts to name your agent.
47
+ Configure `.env` with your `MNEMONIC` (auto-generated for hirers).
48
+
49
+ ## Adding Send Payments to Existing Projects
16
50
 
17
- ## What is included?
51
+ If you scaffolded your agent before the send payment feature was available, you can add it manually. No new npm packages required — `ethers` (already in your `package.json`) has everything needed.
18
52
 
19
- The scaffolded project includes:
20
- - **TypeScript** configuration for modern Node.js development.
21
- - **ESLint & Prettier** setup (implied standards).
22
- - **@openagentmarket/nodejs** SDK integration.
23
- - **Example Agent** code (`index.ts`) demonstrating the basic structure.
24
- - **Environment Configuration** (`.env`) template.
53
+ **1. Add to `.env`:**
25
54
 
26
- ## Getting Started with your new Agent
55
+ ```
56
+ BASE_RPC_URL="https://mainnet.base.org"
57
+ ```
58
+
59
+ **2. Add imports to `index.ts`:**
60
+
61
+ ```typescript
62
+ import { Contract, parseUnits, parseEther, JsonRpcProvider } from 'ethers';
63
+ ```
64
+
65
+ **3. Add task handlers after your existing `agent.onTask(...)` blocks:**
66
+
67
+ ```typescript
68
+ // ── Send USDC on Base ──
69
+ const USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
70
+ const USDC_ABI = [
71
+ "function transfer(address to, uint256 amount) returns (bool)",
72
+ "function balanceOf(address owner) view returns (uint256)"
73
+ ];
74
+
75
+ agent.onTask("send_usdc", async (input) => {
76
+ const provider = new JsonRpcProvider(process.env.BASE_RPC_URL || "https://mainnet.base.org");
77
+ const wallet = agent.getWallet().connect(provider);
78
+ const usdc = new Contract(USDC_ADDRESS, USDC_ABI, wallet);
79
+ const amount = parseUnits(input.amount, 6);
80
+ const tx = await usdc.transfer(input.to, amount);
81
+ const receipt = await tx.wait();
82
+ return { success: true, txHash: receipt.hash, chain: "base", currency: "USDC", amount: input.amount, to: input.to };
83
+ });
84
+
85
+ // ── Send ETH on Base ──
86
+ agent.onTask("send_eth", async (input) => {
87
+ const provider = new JsonRpcProvider(process.env.BASE_RPC_URL || "https://mainnet.base.org");
88
+ const wallet = agent.getWallet().connect(provider);
89
+ const tx = await wallet.sendTransaction({ to: input.to, value: parseEther(input.amount) });
90
+ const receipt = await tx.wait();
91
+ return { success: true, txHash: receipt.hash, chain: "base", currency: "ETH", amount: input.amount, to: input.to };
92
+ });
93
+ ```
27
94
 
28
- Once created:
95
+ **4. Add `"send_usdc"` and `"send_eth"` to your agent's `skills` array in the `card` config.**
29
96
 
30
- 1. Navigate to your project directory: `cd <your-agent-name>`
31
- 2. Install dependencies: `pnpm install` (or `npm install`)
32
- 3. Configure your `.env` file with a valid mnemonic.
33
- 4. Start dev mode: `pnpm dev`
97
+ **5. Fund your agent's wallet** with USDC or ETH on Base before sending.
package/dist/index.js CHANGED
@@ -306,11 +306,17 @@ async function scaffoldWorker() {
306
306
  {
307
307
  type: 'confirm',
308
308
  name: 'includePayments',
309
- message: 'Include x402 payments?',
309
+ message: 'Include x402 payments (charge for your services)?',
310
+ initial: false
311
+ },
312
+ {
313
+ type: 'confirm',
314
+ name: 'includeSendPayments',
315
+ message: 'Include send payments (USDC/ETH on Base)?',
310
316
  initial: false
311
317
  }
312
318
  ]);
313
- const { agentName, description, skills, includeRegistration, includePayments } = response;
319
+ const { agentName, description, skills, includeRegistration, includePayments, includeSendPayments } = response;
314
320
  if (!agentName) {
315
321
  console.log(kleur.red('Cancelled.'));
316
322
  process.exit(1);
@@ -354,14 +360,30 @@ async function scaffoldWorker() {
354
360
  envContent += 'REGISTRATION_PRIVATE_KEY=""\n';
355
361
  envContent += 'PINATA_JWT=""\n';
356
362
  }
363
+ if (includeSendPayments) {
364
+ envContent += 'BASE_RPC_URL="https://mainnet.base.org"\n';
365
+ }
357
366
  fs.writeFileSync(path.join(targetDir, '.env'), envContent);
358
367
  // 4. .gitignore
359
368
  fs.writeFileSync(path.join(targetDir, '.gitignore'), 'node_modules\n.env\ndist\n');
360
369
  // 5. index.ts
361
- const taskHandlers = skillList.map((skill) => `
370
+ // Add send payment skills if enabled
371
+ if (includeSendPayments) {
372
+ if (!skillList.includes('send_usdc'))
373
+ skillList.push('send_usdc');
374
+ if (!skillList.includes('send_eth'))
375
+ skillList.push('send_eth');
376
+ }
377
+ const taskHandlers = skillList.map((skill) => {
378
+ if (skill === 'send_usdc')
379
+ return SEND_USDC_HANDLER;
380
+ if (skill === 'send_eth')
381
+ return SEND_ETH_HANDLER;
382
+ return `
362
383
  agent.onTask("${skill}", async (input) => {
363
384
  return { message: \`Handled ${skill} with \${JSON.stringify(input)}\` };
364
- });`).join('\n');
385
+ });`;
386
+ }).join('\n');
365
387
  const paymentConfig = includePayments ? `
366
388
  payment: {
367
389
  amount: 5,
@@ -394,8 +416,11 @@ async function registerAgent(agent: any) {
394
416
  const registrationCall = includeRegistration
395
417
  ? '\n // Uncomment to register on-chain:\n // await registerAgent(agent);\n'
396
418
  : '';
419
+ const sendPaymentImports = includeSendPayments
420
+ ? `import { Contract, parseUnits, parseEther, JsonRpcProvider } from 'ethers';\n`
421
+ : '';
397
422
  const indexTs = `import { OpenAgent } from '@openagentmarket/nodejs';
398
- import 'dotenv/config';
423
+ ${sendPaymentImports}import 'dotenv/config';
399
424
 
400
425
  async function main() {
401
426
  const mnemonic = process.env.MNEMONIC;
@@ -455,6 +480,7 @@ main().catch(console.error);
455
480
  `| **Name** | ${agentName} |`,
456
481
  `| **Skills** | ${skillList.join(', ')} |`,
457
482
  `| **Payments** | ${includePayments ? 'Enabled (x402)' : 'Disabled'} |`,
483
+ `| **Send Payments** | ${includeSendPayments ? 'Enabled (USDC/ETH on Base)' : 'Disabled'} |`,
458
484
  `| **Registration** | ${includeRegistration ? 'Included' : 'Not included'} |`,
459
485
  ``,
460
486
  `## Environment Variables`,
@@ -462,6 +488,7 @@ main().catch(console.error);
462
488
  `| Variable | Required | Description |`,
463
489
  `|----------|----------|-------------|`,
464
490
  '| `MNEMONIC` | Yes | Agent wallet seed phrase |',
491
+ includeSendPayments ? '| `BASE_RPC_URL` | For send payments | Base RPC endpoint (default: https://mainnet.base.org) |' : '',
465
492
  includeRegistration ? '| `REGISTRATION_PRIVATE_KEY` | For registration | Wallet paying gas |\n| `PINATA_JWT` | For registration | IPFS metadata upload |' : '',
466
493
  ``,
467
494
  `## Resources`,
@@ -479,6 +506,55 @@ main().catch(console.error);
479
506
  console.log(' # Set your MNEMONIC in .env');
480
507
  console.log(' npm start\n');
481
508
  }
509
+ // ── Send Payment Templates ───────────────────────────────────────────────────
510
+ const SEND_USDC_HANDLER = `
511
+ // ── Send USDC on Base ──
512
+ const USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
513
+ const USDC_ABI = [
514
+ "function transfer(address to, uint256 amount) returns (bool)",
515
+ "function balanceOf(address owner) view returns (uint256)"
516
+ ];
517
+
518
+ agent.onTask("send_usdc", async (input) => {
519
+ const provider = new JsonRpcProvider(process.env.BASE_RPC_URL || "https://mainnet.base.org");
520
+ const wallet = agent.getWallet().connect(provider);
521
+ const usdc = new Contract(USDC_ADDRESS, USDC_ABI, wallet);
522
+
523
+ // USDC has 6 decimals
524
+ const amount = parseUnits(input.amount, 6);
525
+ const tx = await usdc.transfer(input.to, amount);
526
+ const receipt = await tx.wait();
527
+
528
+ return {
529
+ success: true,
530
+ txHash: receipt.hash,
531
+ chain: "base",
532
+ currency: "USDC",
533
+ amount: input.amount,
534
+ to: input.to
535
+ };
536
+ });`;
537
+ const SEND_ETH_HANDLER = `
538
+ // ── Send ETH on Base ──
539
+ agent.onTask("send_eth", async (input) => {
540
+ const provider = new JsonRpcProvider(process.env.BASE_RPC_URL || "https://mainnet.base.org");
541
+ const wallet = agent.getWallet().connect(provider);
542
+
543
+ const tx = await wallet.sendTransaction({
544
+ to: input.to,
545
+ value: parseEther(input.amount)
546
+ });
547
+ const receipt = await tx.wait();
548
+
549
+ return {
550
+ success: true,
551
+ txHash: receipt.hash,
552
+ chain: "base",
553
+ currency: "ETH",
554
+ amount: input.amount,
555
+ to: input.to
556
+ };
557
+ });`;
482
558
  // ── Shared helpers ───────────────────────────────────────────────────────────
483
559
  function writeSharedTsConfig(targetDir) {
484
560
  const tsConfig = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openagentmarket/create-agent",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "CLI to scaffold a new OpenAgent project (hirer or worker)",
5
5
  "type": "module",
6
6
  "bin": {
@@ -23,4 +23,4 @@
23
23
  "typescript": "^5.3.3",
24
24
  "@types/node": "^20.11.20"
25
25
  }
26
- }
26
+ }
package/src/index.ts CHANGED
@@ -325,12 +325,18 @@ async function scaffoldWorker() {
325
325
  {
326
326
  type: 'confirm',
327
327
  name: 'includePayments',
328
- message: 'Include x402 payments?',
328
+ message: 'Include x402 payments (charge for your services)?',
329
+ initial: false
330
+ },
331
+ {
332
+ type: 'confirm',
333
+ name: 'includeSendPayments',
334
+ message: 'Include send payments (USDC/ETH on Base)?',
329
335
  initial: false
330
336
  }
331
337
  ]);
332
338
 
333
- const { agentName, description, skills, includeRegistration, includePayments } = response;
339
+ const { agentName, description, skills, includeRegistration, includePayments, includeSendPayments } = response;
334
340
  if (!agentName) {
335
341
  console.log(kleur.red('Cancelled.'));
336
342
  process.exit(1);
@@ -380,16 +386,29 @@ async function scaffoldWorker() {
380
386
  envContent += 'REGISTRATION_PRIVATE_KEY=""\n';
381
387
  envContent += 'PINATA_JWT=""\n';
382
388
  }
389
+ if (includeSendPayments) {
390
+ envContent += 'BASE_RPC_URL="https://mainnet.base.org"\n';
391
+ }
383
392
  fs.writeFileSync(path.join(targetDir, '.env'), envContent);
384
393
 
385
394
  // 4. .gitignore
386
395
  fs.writeFileSync(path.join(targetDir, '.gitignore'), 'node_modules\n.env\ndist\n');
387
396
 
388
397
  // 5. index.ts
389
- const taskHandlers = skillList.map((skill: string) => `
398
+ // Add send payment skills if enabled
399
+ if (includeSendPayments) {
400
+ if (!skillList.includes('send_usdc')) skillList.push('send_usdc');
401
+ if (!skillList.includes('send_eth')) skillList.push('send_eth');
402
+ }
403
+
404
+ const taskHandlers = skillList.map((skill: string) => {
405
+ if (skill === 'send_usdc') return SEND_USDC_HANDLER;
406
+ if (skill === 'send_eth') return SEND_ETH_HANDLER;
407
+ return `
390
408
  agent.onTask("${skill}", async (input) => {
391
409
  return { message: \`Handled ${skill} with \${JSON.stringify(input)}\` };
392
- });`).join('\n');
410
+ });`;
411
+ }).join('\n');
393
412
 
394
413
  const paymentConfig = includePayments ? `
395
414
  payment: {
@@ -426,8 +445,12 @@ async function registerAgent(agent: any) {
426
445
  ? '\n // Uncomment to register on-chain:\n // await registerAgent(agent);\n'
427
446
  : '';
428
447
 
448
+ const sendPaymentImports = includeSendPayments
449
+ ? `import { Contract, parseUnits, parseEther, JsonRpcProvider } from 'ethers';\n`
450
+ : '';
451
+
429
452
  const indexTs = `import { OpenAgent } from '@openagentmarket/nodejs';
430
- import 'dotenv/config';
453
+ ${sendPaymentImports}import 'dotenv/config';
431
454
 
432
455
  async function main() {
433
456
  const mnemonic = process.env.MNEMONIC;
@@ -488,6 +511,7 @@ main().catch(console.error);
488
511
  `| **Name** | ${agentName} |`,
489
512
  `| **Skills** | ${skillList.join(', ')} |`,
490
513
  `| **Payments** | ${includePayments ? 'Enabled (x402)' : 'Disabled'} |`,
514
+ `| **Send Payments** | ${includeSendPayments ? 'Enabled (USDC/ETH on Base)' : 'Disabled'} |`,
491
515
  `| **Registration** | ${includeRegistration ? 'Included' : 'Not included'} |`,
492
516
  ``,
493
517
  `## Environment Variables`,
@@ -495,6 +519,7 @@ main().catch(console.error);
495
519
  `| Variable | Required | Description |`,
496
520
  `|----------|----------|-------------|`,
497
521
  '| `MNEMONIC` | Yes | Agent wallet seed phrase |',
522
+ includeSendPayments ? '| `BASE_RPC_URL` | For send payments | Base RPC endpoint (default: https://mainnet.base.org) |' : '',
498
523
  includeRegistration ? '| `REGISTRATION_PRIVATE_KEY` | For registration | Wallet paying gas |\n| `PINATA_JWT` | For registration | IPFS metadata upload |' : '',
499
524
  ``,
500
525
  `## Resources`,
@@ -514,6 +539,58 @@ main().catch(console.error);
514
539
  console.log(' npm start\n');
515
540
  }
516
541
 
542
+ // ── Send Payment Templates ───────────────────────────────────────────────────
543
+
544
+ const SEND_USDC_HANDLER = `
545
+ // ── Send USDC on Base ──
546
+ const USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
547
+ const USDC_ABI = [
548
+ "function transfer(address to, uint256 amount) returns (bool)",
549
+ "function balanceOf(address owner) view returns (uint256)"
550
+ ];
551
+
552
+ agent.onTask("send_usdc", async (input) => {
553
+ const provider = new JsonRpcProvider(process.env.BASE_RPC_URL || "https://mainnet.base.org");
554
+ const wallet = agent.getWallet().connect(provider);
555
+ const usdc = new Contract(USDC_ADDRESS, USDC_ABI, wallet);
556
+
557
+ // USDC has 6 decimals
558
+ const amount = parseUnits(input.amount, 6);
559
+ const tx = await usdc.transfer(input.to, amount);
560
+ const receipt = await tx.wait();
561
+
562
+ return {
563
+ success: true,
564
+ txHash: receipt.hash,
565
+ chain: "base",
566
+ currency: "USDC",
567
+ amount: input.amount,
568
+ to: input.to
569
+ };
570
+ });`;
571
+
572
+ const SEND_ETH_HANDLER = `
573
+ // ── Send ETH on Base ──
574
+ agent.onTask("send_eth", async (input) => {
575
+ const provider = new JsonRpcProvider(process.env.BASE_RPC_URL || "https://mainnet.base.org");
576
+ const wallet = agent.getWallet().connect(provider);
577
+
578
+ const tx = await wallet.sendTransaction({
579
+ to: input.to,
580
+ value: parseEther(input.amount)
581
+ });
582
+ const receipt = await tx.wait();
583
+
584
+ return {
585
+ success: true,
586
+ txHash: receipt.hash,
587
+ chain: "base",
588
+ currency: "ETH",
589
+ amount: input.amount,
590
+ to: input.to
591
+ };
592
+ });`;
593
+
517
594
  // ── Shared helpers ───────────────────────────────────────────────────────────
518
595
 
519
596
  function writeSharedTsConfig(targetDir: string) {