agentic-x402 0.1.2 → 0.2.2

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
@@ -27,20 +27,26 @@ x402 --version
27
27
 
28
28
  ### Configure
29
29
 
30
- Set your wallet private key (required):
30
+ Run the interactive setup to create a new wallet:
31
31
 
32
32
  ```bash
33
- export EVM_PRIVATE_KEY=0x...your_private_key...
33
+ x402 setup
34
34
  ```
35
35
 
36
- Or create a persistent config file:
36
+ This will:
37
+ 1. Generate a new wallet (recommended) or accept an existing key
38
+ 2. Save configuration to `~/.x402/.env`
39
+ 3. Display your wallet address for funding
40
+ 4. Show your private key for backup
41
+
42
+ **Back up your private key immediately!** See [Backup](#backup-your-private-key) below.
43
+
44
+ #### Manual Configuration
45
+
46
+ Alternatively, set the environment variable directly:
37
47
 
38
48
  ```bash
39
- mkdir -p ~/.x402
40
- cat > ~/.x402/.env << 'EOF'
41
- EVM_PRIVATE_KEY=0x...your_private_key...
42
- X402_NETWORK=mainnet
43
- EOF
49
+ export EVM_PRIVATE_KEY=0x...your_private_key...
44
50
  ```
45
51
 
46
52
  ### Development / Local Install
@@ -56,24 +62,38 @@ cp config/example.env .env
56
62
  ## Quick Start
57
63
 
58
64
  ```bash
59
- # 1. Configure your wallet
60
- export EVM_PRIVATE_KEY=0x...your_private_key...
65
+ # 1. Create a wallet
66
+ x402 setup
61
67
 
62
- # 2. Check balance
68
+ # 2. Fund your wallet with USDC on Base (send to the address shown)
69
+
70
+ # 3. Check balance
63
71
  x402 balance
64
72
 
65
- # 3. Pay for a resource
73
+ # 4. Pay for a resource
66
74
  x402 pay https://api.example.com/paid-endpoint
67
75
 
68
- # 4. Fetch with auto-payment
76
+ # 5. Fetch with auto-payment
69
77
  x402 fetch https://api.example.com/data --json
70
78
 
71
- # 5. Create a payment link (requires x402-links-server)
79
+ # 6. Create a payment link (requires x402-links-server)
72
80
  x402 create-link --name "My API" --price 1.00 --url https://api.example.com/premium
73
81
  ```
74
82
 
75
83
  ## Commands
76
84
 
85
+ ### setup — Create or Configure Wallet
86
+
87
+ Interactive setup that generates a new wallet or accepts an existing private key. Saves configuration to `~/.x402/.env`.
88
+
89
+ ```bash
90
+ x402 setup
91
+ ```
92
+
93
+ **Security:** If you choose to use an existing private key, you'll see a warning. We recommend using a **dedicated wallet** with limited funds for automated agents.
94
+
95
+ ---
96
+
77
97
  ### balance — Check Wallet Balances
78
98
 
79
99
  Show your wallet address, USDC balance (for payments), and ETH balance (for gas). Warns if either balance is low.
@@ -142,7 +162,7 @@ x402 fetch https://api.example.com/submit --method POST --body '{"key":"value"}'
142
162
 
143
163
  ### create-link — Create a Payment Link
144
164
 
145
- Create a payment link via the [21.cash](https://21.cash) x402-links-server. You can gate a URL or text content behind a USDC payment. Requires `X402_LINKS_API_URL` and `X402_LINKS_API_KEY` environment variables.
165
+ Create a payment link via the [21.cash](https://21.cash) x402-links-server. You can gate a URL or text content behind a USDC payment. Requires `X402_LINKS_API_URL` environment variable. Link creation costs $0.10 USDC, paid automatically via x402.
146
166
 
147
167
  ```bash
148
168
  x402 create-link --name "Premium Guide" --price 5.00 --url https://mysite.com/guide.pdf
@@ -210,7 +230,6 @@ Config is loaded from these locations (in order of priority):
210
230
  | Variable | Description |
211
231
  |----------|-------------|
212
232
  | `X402_LINKS_API_URL` | Base URL of x402-links-server (e.g., `https://21.cash`) |
213
- | `X402_LINKS_API_KEY` | API key for programmatic link creation |
214
233
 
215
234
  ## Global Options
216
235
 
@@ -223,6 +242,7 @@ Config is loaded from these locations (in order of priority):
223
242
 
224
243
  | Category | Command | Description |
225
244
  |----------|---------|-------------|
245
+ | **Setup** | `setup` | Create or configure your x402 wallet |
226
246
  | **Info** | `balance` | Check wallet USDC and ETH balances |
227
247
  | **Payments** | `pay <url>` | Pay for an x402-gated resource (verbose output) |
228
248
  | **Payments** | `fetch <url>` | Fetch with auto-payment (pipe-friendly `--json`/`--raw`) |
@@ -244,6 +264,50 @@ x402 fetch https://api.example.com/data --json
244
264
  x402 fetch https://api.example.com/data --raw
245
265
  ```
246
266
 
267
+ ## Backup Your Private Key
268
+
269
+ Your private key is stored in `~/.x402/.env`. **If lost, your funds cannot be recovered.**
270
+
271
+ ### Recommended Backup Methods
272
+
273
+ 1. **Password Manager** (Recommended)
274
+ - Store in 1Password, Bitwarden, or similar
275
+ - Create a secure note with your private key
276
+
277
+ 2. **Encrypted File**
278
+ ```bash
279
+ gpg -c ~/.x402/.env
280
+ # Store the encrypted .env.gpg file securely
281
+ ```
282
+
283
+ 3. **Paper Backup** (for larger amounts)
284
+ - Write down the private key
285
+ - Store in a safe or safety deposit box
286
+
287
+ ### View Your Private Key
288
+
289
+ ```bash
290
+ cat ~/.x402/.env | grep EVM_PRIVATE_KEY
291
+ ```
292
+
293
+ ### Recovery
294
+
295
+ ```bash
296
+ mkdir -p ~/.x402
297
+ echo "EVM_PRIVATE_KEY=0x...your_backed_up_key..." > ~/.x402/.env
298
+ chmod 600 ~/.x402/.env
299
+ x402 balance # verify
300
+ ```
301
+
302
+ ## Security Best Practices
303
+
304
+ - **Use a dedicated wallet** — Never use your main wallet with automated agents
305
+ - **Limit funds** — Only transfer what you need for payments
306
+ - **Set payment limits** — Configure `X402_MAX_PAYMENT_USD` to cap exposure
307
+ - **Test first** — Use `X402_NETWORK=testnet` before mainnet
308
+ - **Protect the config** — Keep `~/.x402/.env` with 600 permissions
309
+ - **Never share** — Your private key gives full access to your wallet
310
+
247
311
  ## License
248
312
 
249
313
  MIT
package/SKILL.md CHANGED
@@ -5,7 +5,7 @@ license: MIT
5
5
  compatibility: Requires Node.js 20+, network access to x402 facilitators and EVM chains
6
6
  metadata:
7
7
  author: monemetrics
8
- version: "0.1.0"
8
+ version: "0.2.1"
9
9
  allowed-tools: Bash(x402:*) Bash(npm:*) Read
10
10
  ---
11
11
 
@@ -17,6 +17,7 @@ Pay for x402-gated APIs and content using USDC on Base. This skill enables agent
17
17
 
18
18
  | Command | Description |
19
19
  |---------|-------------|
20
+ | `x402 setup` | Create or configure wallet |
20
21
  | `x402 balance` | Check USDC and ETH balances |
21
22
  | `x402 pay <url>` | Pay for a gated resource |
22
23
  | `x402 fetch <url>` | Fetch with auto-payment |
@@ -38,20 +39,33 @@ x402 --version
38
39
 
39
40
  ## Setup
40
41
 
41
- Configure your wallet private key (required):
42
+ Run the interactive setup to create a new wallet:
43
+
44
+ ```bash
45
+ x402 setup
46
+ ```
47
+
48
+ This will:
49
+ 1. Generate a new wallet (recommended) or accept an existing key
50
+ 2. Save configuration to `~/.x402/.env`
51
+ 3. Display your wallet address for funding
52
+
53
+ **Important:** Back up your private key immediately after setup!
54
+
55
+ ### Manual Configuration
56
+
57
+ Alternatively, set the environment variable directly:
42
58
 
43
59
  ```bash
44
60
  export EVM_PRIVATE_KEY=0x...your_private_key...
45
61
  ```
46
62
 
47
- Or create a persistent config file:
63
+ Or create a config file:
48
64
 
49
65
  ```bash
50
66
  mkdir -p ~/.x402
51
- cat > ~/.x402/.env << 'EOF'
52
- EVM_PRIVATE_KEY=0x...your_private_key...
53
- X402_NETWORK=mainnet
54
- EOF
67
+ echo "EVM_PRIVATE_KEY=0x..." > ~/.x402/.env
68
+ chmod 600 ~/.x402/.env
55
69
  ```
56
70
 
57
71
  Verify setup:
@@ -116,7 +130,6 @@ Create payment links to monetize your own content using x402-links-server:
116
130
  Add to `.env`:
117
131
  ```bash
118
132
  X402_LINKS_API_URL=https://your-x402-links-server.com
119
- X402_LINKS_API_KEY=your_api_key
120
133
  ```
121
134
 
122
135
  ### Create a link
@@ -241,7 +254,6 @@ x402 link-info <router-address> [--json]
241
254
  | `X402_SLIPPAGE_BPS` | Slippage tolerance in basis points (100 bps = 1%) | `50` |
242
255
  | `X402_VERBOSE` | Enable verbose logging (`1` = on, `0` = off) | `0` |
243
256
  | `X402_LINKS_API_URL` | Base URL of x402-links-server (e.g., `https://21.cash`) | — |
244
- | `X402_LINKS_API_KEY` | API key for programmatic link creation | — |
245
257
 
246
258
  ## Supported Networks
247
259
 
@@ -299,12 +311,53 @@ Ensure your wallet has funds on the correct network:
299
311
  - `X402_NETWORK=mainnet` → Base mainnet
300
312
  - `X402_NETWORK=testnet` → Base Sepolia
301
313
 
302
- ## Security Notes
314
+ ## Backup Your Private Key
315
+
316
+ Your private key is stored in `~/.x402/.env`. If lost, your funds cannot be recovered.
317
+
318
+ ### Recommended Backup Methods
319
+
320
+ 1. **Password Manager** (Recommended)
321
+ - Store in 1Password, Bitwarden, or similar
322
+ - Create a secure note with your private key
323
+ - Tag it for easy retrieval
324
+
325
+ 2. **Encrypted File**
326
+ ```bash
327
+ # Encrypt with GPG
328
+ gpg -c ~/.x402/.env
329
+ # Creates ~/.x402/.env.gpg - store this backup securely
330
+ ```
331
+
332
+ 3. **Paper Backup** (for larger amounts)
333
+ - Write down the private key
334
+ - Store in a safe or safety deposit box
335
+ - Never store digitally unencrypted
336
+
337
+ ### View Your Private Key
338
+
339
+ ```bash
340
+ cat ~/.x402/.env | grep EVM_PRIVATE_KEY
341
+ ```
342
+
343
+ ### Recovery
344
+
345
+ To restore from backup:
346
+ ```bash
347
+ mkdir -p ~/.x402
348
+ echo "EVM_PRIVATE_KEY=0x...your_backed_up_key..." > ~/.x402/.env
349
+ chmod 600 ~/.x402/.env
350
+ x402 balance # verify
351
+ ```
352
+
353
+ ## Security Best Practices
303
354
 
304
- - Never share your private key
305
- - Start with testnet to verify setup
306
- - Set reasonable payment limits
307
- - Review payment amounts before confirming
355
+ - **Use a dedicated wallet** — Never use your main wallet with automated agents
356
+ - **Limit funds** Only transfer what you need for payments
357
+ - **Set payment limits** — Configure `X402_MAX_PAYMENT_USD` to cap exposure
358
+ - **Test first** Use `X402_NETWORK=testnet` with test tokens before mainnet
359
+ - **Protect the config** — `~/.x402/.env` has 600 permissions; keep it that way
360
+ - **Never share** — Your private key gives full access to your wallet
308
361
 
309
362
  ## Links
310
363
 
package/bin/cli.ts CHANGED
@@ -11,10 +11,17 @@ const scriptsDir = resolve(__dirname, '../scripts');
11
11
  interface Command {
12
12
  script: string;
13
13
  description: string;
14
- category: 'info' | 'payments' | 'links';
14
+ category: 'setup' | 'info' | 'payments' | 'links';
15
15
  }
16
16
 
17
17
  const commands: Record<string, Command> = {
18
+ // Setup commands
19
+ setup: {
20
+ script: 'commands/setup.ts',
21
+ description: 'Create or configure your x402 wallet',
22
+ category: 'setup',
23
+ },
24
+
18
25
  // Info commands
19
26
  balance: {
20
27
  script: 'commands/balance.ts',
@@ -53,6 +60,9 @@ x402 - Agent skill for x402 payments
53
60
 
54
61
  Usage: x402 <command> [arguments]
55
62
 
63
+ Setup:
64
+ setup Create or configure your x402 wallet
65
+
56
66
  Info Commands:
57
67
  balance Check wallet USDC and ETH balances
58
68
 
@@ -68,26 +78,18 @@ Options:
68
78
  -h, --help Show this help
69
79
  -v, --version Show version
70
80
 
71
- Environment Variables:
72
- EVM_PRIVATE_KEY Wallet private key (required)
73
- X402_NETWORK Network: mainnet or testnet (default: mainnet)
74
- X402_MAX_PAYMENT_USD Max payment limit in USD (default: 10)
75
- X402_FACILITATOR_URL Custom facilitator URL
76
- X402_LINKS_API_URL x402-links-server URL (for link commands)
77
- X402_LINKS_API_KEY API key for x402-links-server
78
-
79
- Examples:
80
- x402 balance
81
- x402 pay https://api.example.com/data
82
- x402 fetch https://api.example.com/resource --json
83
- x402 create-link --name "Guide" --price 5.00 --url https://mysite.com/guide
81
+ Getting Started:
82
+ 1. Run "x402 setup" to create a new wallet
83
+ 2. Fund your wallet with USDC on Base
84
+ 3. Run "x402 balance" to verify
85
+ 4. Use "x402 pay <url>" to pay for resources
84
86
 
85
87
  For command-specific help: x402 <command> --help
86
88
  `);
87
89
  }
88
90
 
89
91
  function showVersion() {
90
- console.log('agentic-x402 v0.1.0');
92
+ console.log('agentic-x402 v0.2.1');
91
93
  }
92
94
 
93
95
  async function main() {
@@ -39,13 +39,10 @@ X402_MAX_PAYMENT_USD=10
39
39
  # 21CASH INTEGRATION (Optional - for creating payment links)
40
40
  # =============================================================================
41
41
 
42
- # x402-links-server API URL
42
+ # x402-links-server API URL (link creation is gated by x402 payment)
43
43
  # Example: https://your-21cash-instance.com or https://21.cash
44
44
  # X402_LINKS_API_URL=https://your-server.com
45
45
 
46
- # API key for programmatic link creation
47
- # X402_LINKS_API_KEY=your_api_key_here
48
-
49
46
  # =============================================================================
50
47
  # DEBUG
51
48
  # =============================================================================
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-x402",
3
- "version": "0.1.2",
3
+ "version": "0.2.2",
4
4
  "description": "Agent skill for x402 payments - pay for and sell gated content",
5
5
  "type": "module",
6
6
  "bin": {
@@ -14,6 +14,7 @@
14
14
  "SKILL.md"
15
15
  ],
16
16
  "scripts": {
17
+ "setup": "tsx scripts/commands/setup.ts",
17
18
  "pay": "tsx scripts/commands/pay.ts",
18
19
  "fetch": "tsx scripts/commands/fetch-paid.ts",
19
20
  "balance": "tsx scripts/commands/balance.ts",
@@ -57,7 +57,6 @@ Options:
57
57
 
58
58
  Environment:
59
59
  X402_LINKS_API_URL Base URL of x402-links-server (required)
60
- X402_LINKS_API_KEY API key for programmatic access (required)
61
60
 
62
61
  Examples:
63
62
  x402 create-link --name "Premium Guide" --price 5.00 --url https://mysite.com/guide.pdf
@@ -75,12 +74,6 @@ Examples:
75
74
  process.exit(1);
76
75
  }
77
76
 
78
- if (!config.x402LinksApiKey) {
79
- console.error('Error: X402_LINKS_API_KEY environment variable is required');
80
- console.error('This is the API key for programmatic access to x402-links-server');
81
- process.exit(1);
82
- }
83
-
84
77
  const name = flags.name as string;
85
78
  const price = flags.price as string;
86
79
  const gatedUrl = flags.url as string | undefined;
@@ -142,11 +135,10 @@ Examples:
142
135
 
143
136
  const apiUrl = `${config.x402LinksApiUrl}/api/links/programmatic`;
144
137
 
145
- const response = await fetch(apiUrl, {
138
+ const response = await client.fetchWithPayment(apiUrl, {
146
139
  method: 'POST',
147
140
  headers: {
148
141
  'Content-Type': 'application/json',
149
- 'X-API-Key': config.x402LinksApiKey,
150
142
  },
151
143
  body: JSON.stringify(requestBody),
152
144
  });
@@ -0,0 +1,296 @@
1
+ #!/usr/bin/env npx tsx
2
+ // x402 Agent Skill - Wallet Setup
3
+ // Creates a new wallet or configures an existing one
4
+
5
+ import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
6
+ import * as fs from 'fs';
7
+ import * as path from 'path';
8
+ import * as readline from 'readline';
9
+ import { homedir } from 'os';
10
+
11
+ // Global config directory: ~/.x402/
12
+ const CONFIG_DIR = path.join(homedir(), '.x402');
13
+ const CONFIG_PATH = path.join(CONFIG_DIR, '.env');
14
+
15
+ interface SetupResult {
16
+ success: boolean;
17
+ walletAddress?: string;
18
+ privateKey?: string;
19
+ isNewWallet?: boolean;
20
+ error?: string;
21
+ }
22
+
23
+ function createReadline(): readline.Interface {
24
+ return readline.createInterface({
25
+ input: process.stdin,
26
+ output: process.stdout,
27
+ });
28
+ }
29
+
30
+ function prompt(rl: readline.Interface, question: string): Promise<string> {
31
+ return new Promise((resolve) => {
32
+ rl.question(question, (answer) => {
33
+ resolve(answer.trim());
34
+ });
35
+ });
36
+ }
37
+
38
+ function isValidPrivateKey(key: string): boolean {
39
+ return /^0x[a-fA-F0-9]{64}$/.test(key);
40
+ }
41
+
42
+ function ensureConfigDir(): void {
43
+ if (!fs.existsSync(CONFIG_DIR)) {
44
+ fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
45
+ }
46
+ }
47
+
48
+ function backupExistingConfig(): string | null {
49
+ if (!fs.existsSync(CONFIG_PATH)) {
50
+ return null;
51
+ }
52
+
53
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
54
+ const backupPath = path.join(CONFIG_DIR, `.env.backup.${timestamp}`);
55
+
56
+ fs.copyFileSync(CONFIG_PATH, backupPath);
57
+ fs.chmodSync(backupPath, 0o600);
58
+
59
+ return backupPath;
60
+ }
61
+
62
+ async function main(): Promise<SetupResult> {
63
+ console.log('x402 Agent Skill - Wallet Setup');
64
+ console.log('================================\n');
65
+
66
+ // Check if config already exists
67
+ if (fs.existsSync(CONFIG_PATH)) {
68
+ console.log('Existing config found!');
69
+ console.log(`Location: ${CONFIG_PATH}\n`);
70
+
71
+ // Read existing config and show wallet address
72
+ const envContent = fs.readFileSync(CONFIG_PATH, 'utf-8');
73
+ const keyMatch = envContent.match(/EVM_PRIVATE_KEY=0x([a-fA-F0-9]{64})/);
74
+
75
+ if (keyMatch) {
76
+ const existingKey = `0x${keyMatch[1]}` as `0x${string}`;
77
+ const account = privateKeyToAccount(existingKey);
78
+
79
+ console.log('Current Configuration');
80
+ console.log('---------------------');
81
+ console.log(`Wallet Address: ${account.address}`);
82
+ console.log(`Config File: ${CONFIG_PATH}`);
83
+
84
+ const rl = createReadline();
85
+ console.log('\nOptions:');
86
+ console.log(' 1) Keep existing config (exit)');
87
+ console.log(' 2) Create new wallet (backs up existing config)\n');
88
+
89
+ let choice = '';
90
+ while (choice !== '1' && choice !== '2') {
91
+ choice = await prompt(rl, 'Enter choice (1 or 2): ');
92
+ if (choice !== '1' && choice !== '2') {
93
+ console.log('Please enter 1 or 2');
94
+ }
95
+ }
96
+
97
+ if (choice === '1') {
98
+ rl.close();
99
+ console.log('\nKeeping existing config.');
100
+ console.log(`\nTo check your balance:`);
101
+ console.log(` x402 balance`);
102
+
103
+ return {
104
+ success: true,
105
+ walletAddress: account.address,
106
+ };
107
+ }
108
+
109
+ // User wants to reconfigure - backup first
110
+ rl.close();
111
+ const backupPath = backupExistingConfig();
112
+ console.log(`\nExisting config backed up to:`);
113
+ console.log(` ${backupPath}`);
114
+ console.log('');
115
+
116
+ // Continue with setup flow below...
117
+ } else {
118
+ // Config exists but is invalid - back it up and continue
119
+ const backupPath = backupExistingConfig();
120
+ console.log('Invalid config file found (missing private key).');
121
+ console.log(`Backed up to: ${backupPath}\n`);
122
+ }
123
+ }
124
+
125
+ const rl = createReadline();
126
+
127
+ // Step 1: Wallet choice
128
+ console.log('Step 1/2: Wallet Setup');
129
+ console.log('----------------------');
130
+ console.log('Do you have an existing wallet private key?\n');
131
+ console.log(' 1) Generate a NEW wallet (Recommended for agents)');
132
+ console.log(' 2) Use an EXISTING private key\n');
133
+
134
+ let choice = '';
135
+ while (choice !== '1' && choice !== '2') {
136
+ choice = await prompt(rl, 'Enter choice (1 or 2): ');
137
+ if (choice !== '1' && choice !== '2') {
138
+ console.log('Please enter 1 or 2');
139
+ }
140
+ }
141
+
142
+ let privateKey: `0x${string}`;
143
+ let isNewWallet = false;
144
+
145
+ if (choice === '1') {
146
+ // Generate new wallet (recommended)
147
+ console.log('\nGenerating new wallet...');
148
+ privateKey = generatePrivateKey();
149
+ isNewWallet = true;
150
+ console.log('New wallet created!\n');
151
+ } else {
152
+ // User wants to use existing key - show warnings
153
+ console.log('\n' + '='.repeat(60));
154
+ console.log(' SECURITY WARNING');
155
+ console.log('='.repeat(60));
156
+ console.log('\nUsing your main wallet with automated agents is RISKY:');
157
+ console.log('');
158
+ console.log(' - Agents can sign transactions without your approval');
159
+ console.log(' - A bug or misconfiguration could drain funds');
160
+ console.log(' - Private keys stored in env files can be exposed');
161
+ console.log('');
162
+ console.log('RECOMMENDED: Use a DEDICATED wallet with limited funds.');
163
+ console.log('Only transfer what you need for payments to this wallet.');
164
+ console.log('='.repeat(60) + '\n');
165
+
166
+ const confirm = await prompt(rl, 'I understand the risks (type "yes" to continue): ');
167
+
168
+ if (confirm.toLowerCase() !== 'yes') {
169
+ console.log('\nSetup cancelled. Run "x402 setup" again to generate a new wallet.');
170
+ rl.close();
171
+ return { success: false, error: 'User cancelled setup' };
172
+ }
173
+
174
+ console.log('\nEnter your private key (0x... format):\n');
175
+
176
+ // Loop until we get a valid key
177
+ let inputKey = '';
178
+ while (!isValidPrivateKey(inputKey)) {
179
+ inputKey = await prompt(rl, 'Private key: ');
180
+
181
+ if (!isValidPrivateKey(inputKey)) {
182
+ console.log('Invalid private key format. Must be 0x followed by 64 hex characters.');
183
+ console.log('Example: 0x1234...abcd (66 characters total)\n');
184
+ }
185
+ }
186
+
187
+ privateKey = inputKey as `0x${string}`;
188
+ console.log('\nPrivate key accepted');
189
+ }
190
+
191
+ rl.close();
192
+
193
+ // Derive account from private key
194
+ const account = privateKeyToAccount(privateKey);
195
+ console.log(`Wallet Address: ${account.address}\n`);
196
+
197
+ // Step 2: Create config
198
+ console.log('Step 2/2: Saving configuration...');
199
+ ensureConfigDir();
200
+
201
+ const envContent = `# x402 Agent Skill Configuration
202
+ # Location: ~/.x402/.env
203
+ # Created: ${new Date().toISOString()}
204
+ #
205
+ # WARNING: Keep this file secret! Never share your private key!
206
+ # This wallet can sign payment transactions automatically.
207
+
208
+ # Your wallet private key (required)
209
+ EVM_PRIVATE_KEY=${privateKey}
210
+
211
+ # Network: mainnet or testnet
212
+ # mainnet = Base (chain 8453) - real USDC
213
+ # testnet = Base Sepolia (chain 84532) - test tokens
214
+ X402_NETWORK=mainnet
215
+
216
+ # Maximum payment limit in USD (safety feature)
217
+ # Payments exceeding this will be rejected
218
+ X402_MAX_PAYMENT_USD=10
219
+
220
+ # Verbose logging (0 = off, 1 = on)
221
+ X402_VERBOSE=0
222
+ `;
223
+
224
+ fs.writeFileSync(CONFIG_PATH, envContent, { mode: 0o600 });
225
+ console.log(`Config saved to: ${CONFIG_PATH}\n`);
226
+
227
+ // Final summary
228
+ console.log('='.repeat(50));
229
+ console.log(' SETUP COMPLETE!');
230
+ console.log('='.repeat(50) + '\n');
231
+
232
+ console.log('Your x402 Payment Wallet');
233
+ console.log('------------------------');
234
+ console.log(`Address: ${account.address}`);
235
+ console.log(`Network: Base Mainnet (chain 8453)`);
236
+ console.log(`Config: ${CONFIG_PATH}`);
237
+
238
+ if (isNewWallet) {
239
+ console.log('\n' + '!'.repeat(50));
240
+ console.log(' BACKUP YOUR PRIVATE KEY NOW!');
241
+ console.log('!'.repeat(50));
242
+ console.log('\nYour private key (save this securely):');
243
+ console.log(`\n ${privateKey}\n`);
244
+ console.log('Store this in a password manager or secure location.');
245
+ console.log('If lost, your funds CANNOT be recovered!');
246
+ console.log('!'.repeat(50));
247
+ }
248
+
249
+ console.log('\nNext Steps');
250
+ console.log('----------');
251
+ console.log('1. Fund your wallet with USDC on Base:');
252
+ console.log(` Address: ${account.address}`);
253
+ console.log('');
254
+ console.log('2. Add a small amount of ETH for gas (optional):');
255
+ console.log(' ~0.001 ETH is enough for many transactions');
256
+ console.log('');
257
+ console.log('3. Check your balance:');
258
+ console.log(' x402 balance');
259
+ console.log('');
260
+ console.log('4. Try paying for an x402 resource:');
261
+ console.log(' x402 pay https://some-x402-api.com/endpoint');
262
+
263
+ console.log('\nBackup Reminder');
264
+ console.log('---------------');
265
+ console.log(`Your config is stored at: ${CONFIG_PATH}`);
266
+ console.log('Back up this file or your private key securely!');
267
+ console.log('Consider using a password manager like 1Password or Bitwarden.');
268
+
269
+ console.log('\nSecurity Tips');
270
+ console.log('-------------');
271
+ console.log('- Only fund this wallet with what you need');
272
+ console.log('- Set X402_MAX_PAYMENT_USD to limit exposure');
273
+ console.log('- Never share your private key or config file');
274
+ console.log('- Use testnet first to verify everything works');
275
+
276
+ return {
277
+ success: true,
278
+ walletAddress: account.address,
279
+ privateKey: privateKey,
280
+ isNewWallet,
281
+ };
282
+ }
283
+
284
+ // Export for programmatic use
285
+ export { main as setup };
286
+
287
+ // Run if executed directly
288
+ main().then(result => {
289
+ if (!result.success) {
290
+ console.error(`\nSetup failed: ${result.error}`);
291
+ process.exit(1);
292
+ }
293
+ }).catch(error => {
294
+ console.error('Setup error:', error);
295
+ process.exit(1);
296
+ });
@@ -36,7 +36,6 @@ export interface X402Config {
36
36
 
37
37
  // 21cash integration (optional)
38
38
  x402LinksApiUrl?: string;
39
- x402LinksApiKey?: string;
40
39
 
41
40
  // Defaults
42
41
  maxPaymentUsd: number;
@@ -73,7 +72,6 @@ export function getConfig(): X402Config {
73
72
  chainId,
74
73
  facilitatorUrl: getOptionalEnv('X402_FACILITATOR_URL', defaultFacilitator),
75
74
  x402LinksApiUrl: process.env.X402_LINKS_API_URL,
76
- x402LinksApiKey: process.env.X402_LINKS_API_KEY,
77
75
  maxPaymentUsd: parseFloat(getOptionalEnv('X402_MAX_PAYMENT_USD', '10')),
78
76
  slippageBps: parseInt(getOptionalEnv('X402_SLIPPAGE_BPS', '50'), 10),
79
77
  verbose: getOptionalEnv('X402_VERBOSE', '0') === '1',