facinet 2.2.2 → 2.3.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/dist/index.js CHANGED
@@ -1,99 +1,643 @@
1
1
  #!/usr/bin/env node
2
+ #!/usr/bin/env node
2
3
  "use strict";
3
- /**
4
- * Facinet CLI - x402 Facilitator Network
5
- *
6
- * Command-line tool for making payments and managing facilitators
7
- * on the x402 payment network.
8
- */
9
- var __importDefault = (this && this.__importDefault) || function (mod) {
10
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ var __create = Object.create;
5
+ var __defProp = Object.defineProperty;
6
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
+ var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getProtoOf = Object.getPrototypeOf;
9
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
19
+ // If the importer is in node compatibility mode or this is not an ESM
20
+ // file that has been converted to a CommonJS file using a Babel-
21
+ // compatible transform (i.e. "__esModule" has not been set), then set
22
+ // "default" to the CommonJS "module.exports" for node compatibility.
23
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
24
+ mod
25
+ ));
26
+
27
+ // src/index.ts
28
+ var import_commander = require("commander");
29
+ var import_chalk4 = __toESM(require("chalk"));
30
+
31
+ // src/commands/pay.ts
32
+ var import_inquirer = __toESM(require("inquirer"));
33
+ var import_chalk = __toESM(require("chalk"));
34
+ var import_ora = __toESM(require("ora"));
35
+ var import_ethers = require("ethers");
36
+
37
+ // src/utils/config.ts
38
+ var import_fs = __toESM(require("fs"));
39
+ var import_path = __toESM(require("path"));
40
+ var import_os = __toESM(require("os"));
41
+ var CONFIG_DIR = import_path.default.join(import_os.default.homedir(), ".facinet");
42
+ var CONFIG_FILE = import_path.default.join(CONFIG_DIR, "config.json");
43
+ function getConfig() {
44
+ try {
45
+ if (!import_fs.default.existsSync(CONFIG_FILE)) {
46
+ return {};
47
+ }
48
+ const data = import_fs.default.readFileSync(CONFIG_FILE, "utf8");
49
+ return JSON.parse(data);
50
+ } catch (error) {
51
+ return {};
52
+ }
53
+ }
54
+ function saveConfig(config) {
55
+ try {
56
+ if (!import_fs.default.existsSync(CONFIG_DIR)) {
57
+ import_fs.default.mkdirSync(CONFIG_DIR, { recursive: true });
58
+ }
59
+ const existingConfig = getConfig();
60
+ const newConfig = { ...existingConfig, ...config };
61
+ import_fs.default.writeFileSync(CONFIG_FILE, JSON.stringify(newConfig, null, 2), "utf8");
62
+ } catch (error) {
63
+ throw new Error(`Failed to save configuration: ${error.message}`);
64
+ }
65
+ }
66
+
67
+ // src/utils/api.ts
68
+ var import_axios = __toESM(require("axios"));
69
+ async function listFacilitators(apiUrl) {
70
+ try {
71
+ const response = await import_axios.default.get(`${apiUrl}/api/facilitator/list`, {
72
+ timeout: 1e4,
73
+ headers: {
74
+ "User-Agent": "Facinet-CLI/2.3.0"
75
+ }
76
+ });
77
+ if (response.data.success) {
78
+ return response.data.facilitators.filter((f) => f.status === "active");
79
+ }
80
+ return [];
81
+ } catch (error) {
82
+ throw new Error(
83
+ `Failed to fetch facilitators: ${error.message || error.code || "Unknown error"}`
84
+ );
85
+ }
86
+ }
87
+ async function selectRandomFacilitator(apiUrl) {
88
+ const facilitators = await listFacilitators(apiUrl);
89
+ if (facilitators.length === 0) {
90
+ throw new Error("No active facilitators available");
91
+ }
92
+ const randomIndex = Math.floor(Math.random() * facilitators.length);
93
+ return facilitators[randomIndex];
94
+ }
95
+ async function getFacilitatorById(apiUrl, id) {
96
+ try {
97
+ const response = await import_axios.default.get(`${apiUrl}/api/facilitator/list`);
98
+ if (response.data.success) {
99
+ const facilitator2 = response.data.facilitators.find((f) => f.id === id);
100
+ if (!facilitator2) {
101
+ throw new Error("Facilitator not found");
102
+ }
103
+ return facilitator2;
104
+ }
105
+ throw new Error("Failed to fetch facilitator");
106
+ } catch (error) {
107
+ throw new Error(`Failed to get facilitator: ${error.message}`);
108
+ }
109
+ }
110
+ async function getFacilitatorStatus(apiUrl, id) {
111
+ return getFacilitatorById(apiUrl, id);
112
+ }
113
+ async function getFacilitatorBalance(apiUrl, id) {
114
+ try {
115
+ const response = await import_axios.default.post(`${apiUrl}/api/facilitator/balance`, {
116
+ facilitatorId: id
117
+ });
118
+ if (response.data.success) {
119
+ return {
120
+ name: response.data.name,
121
+ wallet: response.data.wallet,
122
+ balance: response.data.balance,
123
+ status: response.data.status
124
+ };
125
+ }
126
+ throw new Error("Failed to fetch balance");
127
+ } catch (error) {
128
+ throw new Error(`Failed to get balance: ${error.message}`);
129
+ }
130
+ }
131
+ async function createFacilitator(apiUrl, payload) {
132
+ try {
133
+ throw new Error(
134
+ "Facilitator creation requires payment flow. Please use the web interface at " + apiUrl
135
+ );
136
+ } catch (error) {
137
+ throw new Error(`Failed to create facilitator: ${error.message}`);
138
+ }
139
+ }
140
+
141
+ // src/commands/pay.ts
142
+ var CHAINS = {
143
+ avalanche: {
144
+ name: "Avalanche Fuji",
145
+ rpcUrl: "https://api.avax-test.network/ext/bc/C/rpc",
146
+ usdcAddress: "0x5425890298aed601595a70AB815c96711a31Bc65",
147
+ chainId: 43113
148
+ },
149
+ ethereum: {
150
+ name: "Ethereum Sepolia",
151
+ rpcUrl: "https://ethereum-sepolia-rpc.publicnode.com",
152
+ usdcAddress: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
153
+ chainId: 11155111
154
+ },
155
+ base: {
156
+ name: "Base Sepolia",
157
+ rpcUrl: "https://sepolia.base.org",
158
+ usdcAddress: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
159
+ chainId: 84532
160
+ },
161
+ polygon: {
162
+ name: "Polygon Amoy",
163
+ rpcUrl: "https://rpc-amoy.polygon.technology",
164
+ usdcAddress: "0x41E94Eb019C0762f9Bfcf9Fb1E58725BfB0e7582",
165
+ chainId: 80002
166
+ }
167
+ };
168
+ async function payCommand(options) {
169
+ console.log(import_chalk.default.cyan("\n\u{1F4B3} Make Payment via x402 Network\n"));
170
+ const config = getConfig();
171
+ if (!config.privateKey) {
172
+ console.log(import_chalk.default.red("\u274C No wallet connected. Run `facinet connect` first."));
173
+ process.exit(1);
174
+ }
175
+ let recipient = options.to;
176
+ if (!recipient) {
177
+ const answer = await import_inquirer.default.prompt([
178
+ {
179
+ type: "input",
180
+ name: "recipient",
181
+ message: "Recipient address:",
182
+ validate: (input) => {
183
+ if (!input.match(/^0x[a-fA-F0-9]{40}$/)) {
184
+ return "Invalid Ethereum address";
185
+ }
186
+ return true;
187
+ }
188
+ }
189
+ ]);
190
+ recipient = answer.recipient;
191
+ }
192
+ const chain = CHAINS[options.chain];
193
+ if (!chain) {
194
+ console.log(import_chalk.default.red(`\u274C Unsupported chain: ${options.chain}. Supported: ${Object.keys(CHAINS).join(", ")}`));
195
+ process.exit(1);
196
+ }
197
+ console.log(import_chalk.default.gray(`
198
+ \u{1F4CA} Payment Details:`));
199
+ console.log(import_chalk.default.gray(` Amount: ${options.amount} USDC`));
200
+ console.log(import_chalk.default.gray(` To: ${recipient}`));
201
+ console.log(import_chalk.default.gray(` Chain: ${chain.name}`));
202
+ console.log(import_chalk.default.gray(` Your Address: ${config.address}
203
+ `));
204
+ const { confirm } = await import_inquirer.default.prompt([
205
+ {
206
+ type: "confirm",
207
+ name: "confirm",
208
+ message: "Proceed with payment?",
209
+ default: true
210
+ }
211
+ ]);
212
+ if (!confirm) {
213
+ console.log(import_chalk.default.yellow("Payment cancelled."));
214
+ process.exit(0);
215
+ }
216
+ let spinner = (0, import_ora.default)("Selecting random facilitator...").start();
217
+ try {
218
+ const facilitator2 = await selectRandomFacilitator(
219
+ config.apiUrl || options.network || "https://x402-avalanche-chi.vercel.app"
220
+ );
221
+ spinner.succeed(`Selected facilitator: ${import_chalk.default.green(facilitator2.name)}`);
222
+ spinner = (0, import_ora.default)("Preparing transaction...").start();
223
+ const wallet = new import_ethers.Wallet(config.privateKey);
224
+ const provider = new import_ethers.JsonRpcProvider(chain.rpcUrl);
225
+ const connectedWallet = wallet.connect(provider);
226
+ const amount = BigInt(parseFloat(options.amount) * 1e6);
227
+ const validAfter = Math.floor(Date.now() / 1e3) - 60;
228
+ const validBefore = validAfter + 3600;
229
+ const nonce = "0x" + Array.from(
230
+ { length: 64 },
231
+ () => Math.floor(Math.random() * 16).toString(16)
232
+ ).join("");
233
+ const domain = {
234
+ name: "USD Coin",
235
+ version: "2",
236
+ chainId: chain.chainId,
237
+ verifyingContract: chain.usdcAddress
238
+ };
239
+ const types = {
240
+ TransferWithAuthorization: [
241
+ { name: "from", type: "address" },
242
+ { name: "to", type: "address" },
243
+ { name: "value", type: "uint256" },
244
+ { name: "validAfter", type: "uint256" },
245
+ { name: "validBefore", type: "uint256" },
246
+ { name: "nonce", type: "bytes32" }
247
+ ]
248
+ };
249
+ const value = {
250
+ from: wallet.address,
251
+ to: recipient,
252
+ value: amount,
253
+ validAfter,
254
+ validBefore,
255
+ nonce
256
+ };
257
+ spinner.text = "Signing authorization...";
258
+ const signature = await connectedWallet.signTypedData(domain, types, value);
259
+ spinner.succeed("Authorization signed!");
260
+ spinner = (0, import_ora.default)("Submitting to facilitator...").start();
261
+ const paymentPayload = {
262
+ signature,
263
+ authorization: {
264
+ from: wallet.address,
265
+ to: recipient,
266
+ value: amount.toString(),
267
+ validAfter: validAfter.toString(),
268
+ validBefore: validBefore.toString(),
269
+ nonce
270
+ }
271
+ };
272
+ const axios2 = require("axios");
273
+ const apiUrl = config.apiUrl || options.network || "https://x402-avalanche-chi.vercel.app";
274
+ const response = await axios2.post(`${apiUrl}/api/x402/settle-custom`, {
275
+ facilitatorId: facilitator2.id,
276
+ paymentPayload
277
+ });
278
+ if (!response.data.success) {
279
+ throw new Error(response.data.error || "Payment failed");
280
+ }
281
+ spinner.succeed("Payment submitted!");
282
+ const txHash = response.data.txHash;
283
+ console.log(import_chalk.default.green("\n\u2705 Payment processed successfully!"));
284
+ console.log(import_chalk.default.gray(`
285
+ \u{1F4C4} Payment Details:`));
286
+ console.log(import_chalk.default.gray(` Facilitator: ${facilitator2.name}`));
287
+ console.log(import_chalk.default.gray(` Amount: ${options.amount} USDC`));
288
+ console.log(import_chalk.default.gray(` Recipient: ${recipient}`));
289
+ console.log(import_chalk.default.gray(` Chain: ${chain.name}`));
290
+ console.log(import_chalk.default.gray(` Transaction: ${txHash}
291
+ `));
292
+ console.log(import_chalk.default.cyan(`\u{1F517} View on explorer: ${chain.name.includes("Avalanche") ? `https://testnet.snowtrace.io/tx/${txHash}` : chain.name.includes("Base") ? `https://sepolia.basescan.org/tx/${txHash}` : chain.name.includes("Polygon") ? `https://amoy.polygonscan.com/tx/${txHash}` : `https://sepolia.etherscan.io/tx/${txHash}`}
293
+ `));
294
+ } catch (error) {
295
+ spinner.fail("Payment failed");
296
+ console.log(import_chalk.default.red(`
297
+ \u274C Error: ${error.message}
298
+ `));
299
+ process.exit(1);
300
+ }
301
+ }
302
+
303
+ // src/commands/facilitator.ts
304
+ var import_inquirer2 = __toESM(require("inquirer"));
305
+ var import_chalk2 = __toESM(require("chalk"));
306
+ var import_ora2 = __toESM(require("ora"));
307
+ var import_ethers2 = require("ethers");
308
+ async function create(options) {
309
+ console.log(import_chalk2.default.cyan("\n\u{1F680} Create New Facilitator\n"));
310
+ const config = getConfig();
311
+ if (!config.privateKey) {
312
+ console.log(import_chalk2.default.red("\u274C No wallet connected. Run `facinet connect` first."));
313
+ process.exit(1);
314
+ }
315
+ const answers = await import_inquirer2.default.prompt([
316
+ {
317
+ type: "input",
318
+ name: "name",
319
+ message: "Facilitator name:",
320
+ when: !options.name,
321
+ validate: (input) => {
322
+ if (input.length < 3 || input.length > 50) {
323
+ return "Name must be between 3 and 50 characters";
324
+ }
325
+ return true;
326
+ }
327
+ },
328
+ {
329
+ type: "input",
330
+ name: "recipient",
331
+ message: "Payment recipient address:",
332
+ when: !options.recipient,
333
+ default: config.address,
334
+ validate: (input) => {
335
+ if (!input.match(/^0x[a-fA-F0-9]{40}$/)) {
336
+ return "Invalid Ethereum address";
337
+ }
338
+ return true;
339
+ }
340
+ }
341
+ ]);
342
+ const name = options.name || answers.name;
343
+ const recipient = options.recipient || answers.recipient;
344
+ console.log(import_chalk2.default.gray(`
345
+ \u{1F4CB} Facilitator Details:`));
346
+ console.log(import_chalk2.default.gray(` Name: ${name}`));
347
+ console.log(import_chalk2.default.gray(` Recipient: ${recipient}`));
348
+ console.log(import_chalk2.default.gray(` Creator: ${config.address}
349
+ `));
350
+ const { confirm } = await import_inquirer2.default.prompt([
351
+ {
352
+ type: "confirm",
353
+ name: "confirm",
354
+ message: "Create facilitator? (Requires 1 USDC registration fee)",
355
+ default: true
356
+ }
357
+ ]);
358
+ if (!confirm) {
359
+ console.log(import_chalk2.default.yellow("Cancelled."));
360
+ process.exit(0);
361
+ }
362
+ const spinner = (0, import_ora2.default)("Creating facilitator...").start();
363
+ try {
364
+ const wallet = new import_ethers2.Wallet(config.privateKey);
365
+ const facilitatorWallet = import_ethers2.Wallet.createRandom();
366
+ spinner.text = "Registering facilitator...";
367
+ const result = await createFacilitator(options.url, {
368
+ name,
369
+ facilitatorWallet: facilitatorWallet.address,
370
+ facilitatorPrivateKey: facilitatorWallet.privateKey,
371
+ paymentRecipient: recipient,
372
+ createdBy: wallet.address
373
+ });
374
+ spinner.succeed("Facilitator created!");
375
+ console.log(import_chalk2.default.green("\n\u2705 Facilitator created successfully!"));
376
+ console.log(import_chalk2.default.gray(`
377
+ \u{1F4C4} Details:`));
378
+ console.log(import_chalk2.default.gray(` ID: ${result.id}`));
379
+ console.log(import_chalk2.default.gray(` Name: ${name}`));
380
+ console.log(import_chalk2.default.gray(` Wallet: ${facilitatorWallet.address}`));
381
+ console.log(import_chalk2.default.gray(` Status: ${result.status}`));
382
+ console.log(import_chalk2.default.yellow(`
383
+ \u26A0\uFE0F IMPORTANT: Save facilitator wallet private key!`));
384
+ console.log(import_chalk2.default.gray(` Private Key: ${facilitatorWallet.privateKey}
385
+ `));
386
+ console.log(import_chalk2.default.cyan("\u{1F4A1} Next steps:"));
387
+ console.log(import_chalk2.default.gray(` 1. Fund facilitator wallet with gas token`));
388
+ console.log(import_chalk2.default.gray(` 2. Check status: facinet facilitator status ${result.id}`));
389
+ console.log(import_chalk2.default.gray(` 3. Monitor balance: facinet facilitator balance ${result.id}
390
+ `));
391
+ } catch (error) {
392
+ spinner.fail("Failed to create facilitator");
393
+ console.log(import_chalk2.default.red(`
394
+ \u274C Error: ${error.message}
395
+ `));
396
+ process.exit(1);
397
+ }
398
+ }
399
+ async function list(options) {
400
+ console.log(import_chalk2.default.cyan("\n\u{1F4CB} Active Facilitators\n"));
401
+ const spinner = (0, import_ora2.default)("Loading facilitators...").start();
402
+ try {
403
+ const facilitators = await listFacilitators(options.url);
404
+ spinner.stop();
405
+ if (facilitators.length === 0) {
406
+ console.log(import_chalk2.default.yellow("No active facilitators found.\n"));
407
+ return;
408
+ }
409
+ console.log(import_chalk2.default.gray(`Found ${facilitators.length} active facilitator(s):
410
+ `));
411
+ facilitators.forEach((fac, index) => {
412
+ console.log(import_chalk2.default.cyan(`${index + 1}. ${fac.name}`));
413
+ console.log(import_chalk2.default.gray(` ID: ${fac.id}`));
414
+ console.log(import_chalk2.default.gray(` Wallet: ${fac.facilitatorWallet}`));
415
+ console.log(
416
+ import_chalk2.default.gray(` Status: ${getStatusEmoji(fac.status)} ${fac.status.toUpperCase()}`)
417
+ );
418
+ console.log(import_chalk2.default.gray(` Payments: ${fac.totalPayments}`));
419
+ console.log(import_chalk2.default.gray(` Created by: ${fac.createdBy}`));
420
+ console.log("");
421
+ });
422
+ } catch (error) {
423
+ spinner.fail("Failed to load facilitators");
424
+ console.log(import_chalk2.default.red(`
425
+ \u274C Error: ${error.message}
426
+ `));
427
+ process.exit(1);
428
+ }
429
+ }
430
+ async function status(id, options) {
431
+ console.log(import_chalk2.default.cyan(`
432
+ \u{1F4CA} Facilitator Status
433
+ `));
434
+ const spinner = (0, import_ora2.default)("Checking status...").start();
435
+ try {
436
+ const fac = await getFacilitatorStatus(options.url, id);
437
+ spinner.stop();
438
+ console.log(import_chalk2.default.cyan(`${fac.name}`));
439
+ console.log(import_chalk2.default.gray(`ID: ${fac.id}
440
+ `));
441
+ console.log(
442
+ import_chalk2.default.gray(
443
+ `Status: ${getStatusEmoji(fac.status)} ${import_chalk2.default.bold(fac.status.toUpperCase())}`
444
+ )
445
+ );
446
+ console.log(import_chalk2.default.gray(`Wallet: ${fac.facilitatorWallet}`));
447
+ console.log(import_chalk2.default.gray(`Recipient: ${fac.paymentRecipient}`));
448
+ console.log(import_chalk2.default.gray(`Total Payments: ${fac.totalPayments}`));
449
+ console.log(import_chalk2.default.gray(`Gas Balance: ${fac.gasBalance || "Unknown"}`));
450
+ console.log(import_chalk2.default.gray(`Created: ${new Date(fac.lastUsed).toLocaleString()}
451
+ `));
452
+ if (fac.status === "needs_funding") {
453
+ console.log(import_chalk2.default.yellow("\u26A0\uFE0F Facilitator needs gas token for fees"));
454
+ console.log(import_chalk2.default.gray(` Send gas token to: ${fac.facilitatorWallet}
455
+ `));
456
+ }
457
+ } catch (error) {
458
+ spinner.fail("Failed to get status");
459
+ console.log(import_chalk2.default.red(`
460
+ \u274C Error: ${error.message}
461
+ `));
462
+ process.exit(1);
463
+ }
464
+ }
465
+ async function balance(id, options) {
466
+ console.log(import_chalk2.default.cyan(`
467
+ \u{1F4B0} Facilitator Balance
468
+ `));
469
+ const spinner = (0, import_ora2.default)("Checking balance...").start();
470
+ try {
471
+ const result = await getFacilitatorBalance(options.url, id);
472
+ spinner.stop();
473
+ console.log(import_chalk2.default.gray(`Facilitator: ${result.name}`));
474
+ console.log(import_chalk2.default.gray(`Wallet: ${result.wallet}
475
+ `));
476
+ console.log(import_chalk2.default.cyan(`Balance: ${import_chalk2.default.bold(result.balance)}`));
477
+ console.log(
478
+ import_chalk2.default.gray(`Status: ${getStatusEmoji(result.status)} ${result.status.toUpperCase()}
479
+ `)
480
+ );
481
+ if (parseFloat(result.balance) < 0.1) {
482
+ console.log(import_chalk2.default.yellow("\u26A0\uFE0F Low balance! Facilitator may become inactive.\n"));
483
+ }
484
+ } catch (error) {
485
+ spinner.fail("Failed to check balance");
486
+ console.log(import_chalk2.default.red(`
487
+ \u274C Error: ${error.message}
488
+ `));
489
+ process.exit(1);
490
+ }
491
+ }
492
+ function getStatusEmoji(status2) {
493
+ switch (status2) {
494
+ case "active":
495
+ return "\u2705";
496
+ case "needs_funding":
497
+ return "\u26A0\uFE0F";
498
+ case "inactive":
499
+ return "\u274C";
500
+ default:
501
+ return "\u2753";
502
+ }
503
+ }
504
+ var facilitatorCommand = {
505
+ create,
506
+ list,
507
+ status,
508
+ balance
11
509
  };
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- const commander_1 = require("commander");
14
- const chalk_1 = __importDefault(require("chalk"));
15
- const pay_1 = require("./commands/pay");
16
- const facilitator_1 = require("./commands/facilitator");
17
- const connect_1 = require("./commands/connect");
18
- const program = new commander_1.Command();
19
- // ASCII Art Banner
20
- console.log(chalk_1.default.cyan(`
21
- ╔═══════════════════════════════════════╗
22
- ║ ║
23
- ║ ███████╗ █████╗ ██████╗██╗███╗ ║
24
- ║ ██╔════╝██╔══██╗██╔════╝██║████╗ ║
25
- ║ █████╗ ███████║██║ ██║██╔██╗
26
- ║ ██╔══╝ ██╔══██║██║ ██║██║╚██╗║
27
- ║ ██║ ██║ ██║╚██████╗██║██║ ╚██║
28
- ║ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝╚═╝ ╚═║
29
- ║ ║
30
- ║ x402 Facilitator Network CLI ║
31
- ║ ║
32
- ╚═══════════════════════════════════════╝
33
- `));
34
- program
35
- .name('facinet')
36
- .description('CLI tool for x402 Facilitator Network')
37
- .version('1.0.0');
38
- // Connect wallet command
39
- program
40
- .command('connect')
41
- .description('Connect your wallet to Facinet')
42
- .action(connect_1.connectCommand);
43
- // Pay command
44
- program
45
- .command('pay')
46
- .description('Make a payment via x402 facilitator network')
47
- .option('-a, --amount <amount>', 'Payment amount in USDC', '1')
48
- .option('-t, --to <address>', 'Recipient address')
49
- .option('-c, --chain <chain>', 'Blockchain network', 'avalanche')
50
- .option('-n, --network <url>', 'Custom network URL')
51
- .action(pay_1.payCommand);
52
- // Facilitator commands
53
- const facilitator = program
54
- .command('facilitator')
55
- .alias('fac')
56
- .description('Manage facilitators');
57
- facilitator
58
- .command('create')
59
- .description('Create a new facilitator')
60
- .option('-n, --name <name>', 'Facilitator name')
61
- .option('-r, --recipient <address>', 'Payment recipient address')
62
- .option('-u, --url <url>', 'API URL', 'https://x402-avalanche-chi.vercel.app')
63
- .action(facilitator_1.facilitatorCommand.create);
64
- facilitator
65
- .command('list')
66
- .description('List all active facilitators')
67
- .option('-u, --url <url>', 'API URL', 'https://x402-avalanche-chi.vercel.app')
68
- .action(facilitator_1.facilitatorCommand.list);
69
- facilitator
70
- .command('status <id>')
71
- .description('Check facilitator status')
72
- .option('-u, --url <url>', 'API URL', 'https://x402-avalanche-chi.vercel.app')
73
- .action(facilitator_1.facilitatorCommand.status);
74
- facilitator
75
- .command('balance <id>')
76
- .description('Check facilitator gas balance')
77
- .option('-u, --url <url>', 'API URL', 'https://x402-avalanche-chi.vercel.app')
78
- .action(facilitator_1.facilitatorCommand.balance);
79
- // Help command
80
- program.on('--help', () => {
81
- console.log('');
82
- console.log(chalk_1.default.cyan('Examples:'));
83
- console.log('');
84
- console.log(' $ facinet connect');
85
- console.log(' $ facinet pay --amount 1 --to 0x123...');
86
- console.log(' $ facinet facilitator create --name "MyNode"');
87
- console.log(' $ facinet facilitator list');
88
- console.log(' $ facinet facilitator status fac_xyz123');
89
- console.log('');
90
- console.log(chalk_1.default.cyan('Documentation:'));
91
- console.log(' https://github.com/your-repo/facinet');
92
- console.log('');
510
+
511
+ // src/commands/connect.ts
512
+ var import_inquirer3 = __toESM(require("inquirer"));
513
+ var import_chalk3 = __toESM(require("chalk"));
514
+ var import_ethers3 = require("ethers");
515
+ var import_ora3 = __toESM(require("ora"));
516
+ async function connectCommand() {
517
+ console.log(import_chalk3.default.cyan("\n\u{1F517} Connect Wallet to Facinet\n"));
518
+ const { method } = await import_inquirer3.default.prompt([
519
+ {
520
+ type: "list",
521
+ name: "method",
522
+ message: "How would you like to connect?",
523
+ choices: [
524
+ { name: "Enter Private Key (for testing)", value: "privateKey" },
525
+ { name: "Generate New Wallet", value: "generate" }
526
+ ]
527
+ }
528
+ ]);
529
+ if (method === "privateKey") {
530
+ const { privateKey } = await import_inquirer3.default.prompt([
531
+ {
532
+ type: "password",
533
+ name: "privateKey",
534
+ message: "Enter your private key:",
535
+ mask: "*"
536
+ }
537
+ ]);
538
+ try {
539
+ const wallet = new import_ethers3.Wallet(privateKey);
540
+ saveConfig({ privateKey, address: wallet.address });
541
+ console.log(import_chalk3.default.green("\n\u2705 Wallet connected successfully!"));
542
+ console.log(import_chalk3.default.gray(`Address: ${wallet.address}`));
543
+ } catch (error) {
544
+ console.log(import_chalk3.default.red("\n\u274C Invalid private key"));
545
+ process.exit(1);
546
+ }
547
+ } else {
548
+ const spinner = (0, import_ora3.default)("Generating new wallet...").start();
549
+ const wallet = import_ethers3.Wallet.createRandom();
550
+ spinner.succeed("Wallet generated!");
551
+ console.log(import_chalk3.default.green("\n\u2705 New wallet created!"));
552
+ console.log(import_chalk3.default.yellow("\n\u26A0\uFE0F IMPORTANT: Save your private key securely!"));
553
+ console.log(import_chalk3.default.gray(`
554
+ Address: ${wallet.address}`));
555
+ console.log(import_chalk3.default.gray(`Private Key: ${wallet.privateKey}`));
556
+ console.log(import_chalk3.default.gray(`Mnemonic: ${wallet.mnemonic?.phrase}
557
+ `));
558
+ const { confirm } = await import_inquirer3.default.prompt([
559
+ {
560
+ type: "confirm",
561
+ name: "confirm",
562
+ message: "Have you saved your private key?",
563
+ default: false
564
+ }
565
+ ]);
566
+ if (!confirm) {
567
+ console.log(import_chalk3.default.red("\nPlease save your private key before continuing."));
568
+ process.exit(0);
569
+ }
570
+ saveConfig({ privateKey: wallet.privateKey, address: wallet.address });
571
+ console.log(import_chalk3.default.green("\u2705 Configuration saved!"));
572
+ }
573
+ const config = getConfig();
574
+ console.log(import_chalk3.default.cyan("\n\u{1F4E1} Network Configuration:"));
575
+ console.log(import_chalk3.default.gray(`Network: ${config.network || "avalanche-fuji"}`));
576
+ console.log(import_chalk3.default.gray(`API URL: ${config.apiUrl || "http://localhost:3000"}
577
+ `));
578
+ }
579
+
580
+ // src/index.ts
581
+ var program = new import_commander.Command();
582
+ console.log(
583
+ import_chalk4.default.cyan(`
584
+ \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
585
+ \u2551 \u2551
586
+ \u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2551
587
+ \u2551 \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2551
588
+ \u2551 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2551
589
+ \u2551 \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2551
590
+ \u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2551
591
+ \u2551 \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2551
592
+ \u2551 \u2551
593
+ \u2551 x402 Facilitator Network CLI \u2551
594
+ \u2551 \u2551
595
+ \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
596
+ `)
597
+ );
598
+ program.name("facinet").description("CLI tool for x402 Facilitator Network").version("2.3.0");
599
+ program.command("connect").description("Connect your wallet to Facinet").action(connectCommand);
600
+ program.command("pay").description("Make a payment via x402 facilitator network").option("-a, --amount <amount>", "Payment amount in USDC", "1").option("-t, --to <address>", "Recipient address").option("-c, --chain <chain>", "Blockchain network (avalanche, ethereum, base, polygon)", "avalanche").option("-n, --network <url>", "Custom network URL").action(payCommand);
601
+ var facilitator = program.command("facilitator").alias("fac").description("Manage facilitators");
602
+ facilitator.command("create").description("Create a new facilitator").option("-n, --name <name>", "Facilitator name").option("-r, --recipient <address>", "Payment recipient address").option(
603
+ "-u, --url <url>",
604
+ "API URL",
605
+ "https://x402-avalanche-chi.vercel.app"
606
+ ).action(facilitatorCommand.create);
607
+ facilitator.command("list").description("List all active facilitators").option(
608
+ "-u, --url <url>",
609
+ "API URL",
610
+ "https://x402-avalanche-chi.vercel.app"
611
+ ).action(facilitatorCommand.list);
612
+ facilitator.command("status <id>").description("Check facilitator status").option(
613
+ "-u, --url <url>",
614
+ "API URL",
615
+ "https://x402-avalanche-chi.vercel.app"
616
+ ).action(facilitatorCommand.status);
617
+ facilitator.command("balance <id>").description("Check facilitator gas balance").option(
618
+ "-u, --url <url>",
619
+ "API URL",
620
+ "https://x402-avalanche-chi.vercel.app"
621
+ ).action(facilitatorCommand.balance);
622
+ program.on("--help", () => {
623
+ console.log("");
624
+ console.log(import_chalk4.default.cyan("Examples:"));
625
+ console.log("");
626
+ console.log(" $ facinet connect");
627
+ console.log(" $ facinet pay --amount 1 --to 0x123... --chain base");
628
+ console.log(' $ facinet facilitator create --name "MyNode"');
629
+ console.log(" $ facinet facilitator list");
630
+ console.log(" $ facinet facilitator status fac_xyz123");
631
+ console.log("");
632
+ console.log(import_chalk4.default.cyan("Supported Chains:"));
633
+ console.log(" avalanche - Avalanche Fuji (Testnet)");
634
+ console.log(" ethereum - Ethereum Sepolia (Testnet)");
635
+ console.log(" base - Base Sepolia (Testnet)");
636
+ console.log(" polygon - Polygon Amoy (Testnet)");
637
+ console.log("");
93
638
  });
94
639
  program.parse(process.argv);
95
- // Show help if no command provided
96
640
  if (!process.argv.slice(2).length) {
97
- program.outputHelp();
641
+ program.outputHelp();
98
642
  }
99
- //# sourceMappingURL=index.js.map
643
+ //# sourceMappingURL=index.js.map