@paylobster/cli 4.3.1 → 4.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.
Files changed (50) hide show
  1. package/README.md +82 -40
  2. package/dist/src/commands/dashboard.d.ts +3 -0
  3. package/dist/src/commands/dashboard.d.ts.map +1 -0
  4. package/dist/src/commands/dashboard.js +67 -0
  5. package/dist/src/commands/dashboard.js.map +1 -0
  6. package/dist/src/commands/export.d.ts +3 -0
  7. package/dist/src/commands/export.d.ts.map +1 -0
  8. package/dist/src/commands/export.js +97 -0
  9. package/dist/src/commands/export.js.map +1 -0
  10. package/dist/src/commands/health.d.ts +3 -0
  11. package/dist/src/commands/health.d.ts.map +1 -0
  12. package/dist/src/commands/health.js +165 -0
  13. package/dist/src/commands/health.js.map +1 -0
  14. package/dist/src/commands/invest.d.ts +3 -0
  15. package/dist/src/commands/invest.d.ts.map +1 -0
  16. package/dist/src/commands/invest.js +721 -0
  17. package/dist/src/commands/invest.js.map +1 -0
  18. package/dist/src/commands/quickstart.d.ts +3 -0
  19. package/dist/src/commands/quickstart.d.ts.map +1 -0
  20. package/dist/src/commands/quickstart.js +138 -0
  21. package/dist/src/commands/quickstart.js.map +1 -0
  22. package/dist/src/commands/search.d.ts +3 -0
  23. package/dist/src/commands/search.d.ts.map +1 -0
  24. package/dist/src/commands/search.js +126 -0
  25. package/dist/src/commands/search.js.map +1 -0
  26. package/dist/src/commands/trust-graph.d.ts +3 -0
  27. package/dist/src/commands/trust-graph.d.ts.map +1 -0
  28. package/dist/src/commands/trust-graph.js +282 -0
  29. package/dist/src/commands/trust-graph.js.map +1 -0
  30. package/dist/src/commands/whoami.d.ts +3 -0
  31. package/dist/src/commands/whoami.d.ts.map +1 -0
  32. package/dist/src/commands/whoami.js +160 -0
  33. package/dist/src/commands/whoami.js.map +1 -0
  34. package/dist/src/index.js +18 -2
  35. package/dist/src/index.js.map +1 -1
  36. package/dist/src/lib/contracts.d.ts +177 -23
  37. package/dist/src/lib/contracts.d.ts.map +1 -1
  38. package/dist/src/lib/contracts.js +151 -0
  39. package/dist/src/lib/contracts.js.map +1 -1
  40. package/package.json +4 -2
  41. package/src/commands/dashboard.ts +69 -0
  42. package/src/commands/export.ts +132 -0
  43. package/src/commands/health.ts +212 -0
  44. package/src/commands/invest.ts +810 -0
  45. package/src/commands/quickstart.ts +150 -0
  46. package/src/commands/search.ts +151 -0
  47. package/src/commands/trust-graph.ts +267 -0
  48. package/src/commands/whoami.ts +172 -0
  49. package/src/index.ts +18 -2
  50. package/src/lib/contracts.ts +159 -0
@@ -0,0 +1,172 @@
1
+ import { Command } from 'commander';
2
+ import { getAgentInfo, getReputation, getCreditStatus, getBalance, getUserEscrowCount, formatUSDC, formatETH } from '../lib/contracts';
3
+ import { getWalletAddress } from '../lib/wallet';
4
+ import { loadConfig } from '../lib/config';
5
+ import { error, outputJSON } from '../lib/display';
6
+ import type { OutputOptions } from '../lib/types';
7
+ import chalk from 'chalk';
8
+ import ora from 'ora';
9
+
10
+ export function createWhoamiCommand(): Command {
11
+ const cmd = new Command('whoami')
12
+ .description('🦞 Show your complete PayLobster profile')
13
+ .option('--json', 'Output as JSON')
14
+ .action(async (options: OutputOptions) => {
15
+ const spinner = ora('Loading your profile...').start();
16
+
17
+ try {
18
+ const address = getWalletAddress() as `0x${string}`;
19
+ const config = loadConfig();
20
+
21
+ // Fetch all data in parallel
22
+ const [agentInfo, reputation, creditStatus, balance, escrowCount] = await Promise.all([
23
+ getAgentInfo(address),
24
+ getReputation(address),
25
+ getCreditStatus(address),
26
+ getBalance(address),
27
+ getUserEscrowCount(address),
28
+ ]);
29
+
30
+ spinner.stop();
31
+
32
+ // Calculate metrics
33
+ const reputationScore = Number(reputation.score);
34
+ const usdcBalance = formatUSDC(balance.usdc);
35
+ const ethBalance = formatETH(balance.eth);
36
+ const creditLimit = formatUSDC(creditStatus.limit);
37
+ const creditAvailable = formatUSDC(creditStatus.available);
38
+ const creditInUse = formatUSDC(creditStatus.inUse);
39
+ const creditUtilization = creditStatus.limit > 0n
40
+ ? ((Number(creditStatus.inUse) / Number(creditStatus.limit)) * 100).toFixed(1)
41
+ : '0';
42
+
43
+ // Calculate total net worth (USDC + credit available)
44
+ const totalNetWorth = parseFloat(usdcBalance) + parseFloat(creditAvailable);
45
+
46
+ // JSON output
47
+ if (outputJSON({
48
+ identity: {
49
+ name: agentInfo.name,
50
+ address,
51
+ registered: agentInfo.registered,
52
+ tokenId: agentInfo.tokenId.toString(),
53
+ registrationDate: agentInfo.registered ? 'N/A' : null, // TODO: get from events
54
+ },
55
+ reputation: {
56
+ score: reputationScore,
57
+ totalInteractions: 0, // TODO: get from events
58
+ successRate: 0, // TODO: calculate
59
+ },
60
+ credit: {
61
+ score: reputationScore, // Using reputation as proxy
62
+ limit: creditLimit,
63
+ available: creditAvailable,
64
+ inUse: creditInUse,
65
+ utilization: parseFloat(creditUtilization),
66
+ },
67
+ treasury: {
68
+ name: null, // TODO: get from TreasuryFactory
69
+ aum: 0,
70
+ budgetAllocation: {},
71
+ memberCount: 0,
72
+ },
73
+ activity: {
74
+ activeEscrows: escrowCount,
75
+ activeStreams: 0, // TODO: get from Stream contract
76
+ },
77
+ balance: {
78
+ usdc: usdcBalance,
79
+ eth: ethBalance,
80
+ totalNetWorth: totalNetWorth.toFixed(2),
81
+ },
82
+ network: config.network,
83
+ }, options)) {
84
+ return;
85
+ }
86
+
87
+ // Pretty output
88
+ console.log('\n' + chalk.cyan.bold('═══════════════════════════════════════════════════════════'));
89
+ console.log(chalk.cyan.bold(' 🦞 PayLobster Profile'));
90
+ console.log(chalk.cyan.bold('═══════════════════════════════════════════════════════════\n'));
91
+
92
+ // Identity Section
93
+ console.log(chalk.bold.underline('👤 IDENTITY'));
94
+ console.log();
95
+ console.log(chalk.gray(' Name: '), agentInfo.registered ? chalk.bold.white(agentInfo.name) : chalk.yellow('Not Registered'));
96
+ console.log(chalk.gray(' Address: '), chalk.dim(address));
97
+ console.log(chalk.gray(' Token ID: '), agentInfo.registered ? chalk.white(`#${agentInfo.tokenId.toString()}`) : chalk.gray('N/A'));
98
+ console.log(chalk.gray(' Network: '), chalk.white(config.network === 'mainnet' ? '🟢 Base Mainnet' : '🟡 Base Sepolia'));
99
+ console.log();
100
+
101
+ // Reputation Section
102
+ console.log(chalk.bold.underline('⭐ REPUTATION'));
103
+ console.log();
104
+
105
+ let reputationColor = chalk.red;
106
+ let reputationEmoji = '❌';
107
+ if (reputationScore >= 80) {
108
+ reputationColor = chalk.green;
109
+ reputationEmoji = '🌟';
110
+ } else if (reputationScore >= 50) {
111
+ reputationColor = chalk.yellow;
112
+ reputationEmoji = '⭐';
113
+ }
114
+
115
+ console.log(chalk.gray(' Score: '), reputationColor.bold(reputationScore.toString()), reputationEmoji);
116
+ console.log(chalk.gray(' Total Txs: '), chalk.white('N/A')); // TODO
117
+ console.log(chalk.gray(' Success Rate: '), chalk.white('N/A')); // TODO
118
+ console.log();
119
+
120
+ // Credit Section
121
+ console.log(chalk.bold.underline('💳 CREDIT'));
122
+ console.log();
123
+ console.log(chalk.gray(' Score: '), reputationColor.bold(reputationScore.toString())); // Using reputation
124
+ console.log(chalk.gray(' Credit Limit: '), chalk.white(creditLimit), chalk.dim('USDC'));
125
+ console.log(chalk.gray(' Available: '), chalk.green(creditAvailable), chalk.dim('USDC'));
126
+ console.log(chalk.gray(' In Use: '), chalk.yellow(creditInUse), chalk.dim('USDC'));
127
+ console.log(chalk.gray(' Utilization: '), chalk.white(creditUtilization + '%'));
128
+ console.log();
129
+
130
+ // Treasury Section
131
+ console.log(chalk.bold.underline('🏦 TREASURY'));
132
+ console.log();
133
+ console.log(chalk.gray(' Name: '), chalk.yellow('Not implemented yet'));
134
+ console.log(chalk.gray(' AUM: '), chalk.white('N/A'));
135
+ console.log(chalk.gray(' Budget: '), chalk.white('N/A'));
136
+ console.log(chalk.gray(' Members: '), chalk.white('N/A'));
137
+ console.log();
138
+
139
+ // Activity Section
140
+ console.log(chalk.bold.underline('📊 ACTIVITY'));
141
+ console.log();
142
+ console.log(chalk.gray(' Active Escrows: '), chalk.white(escrowCount.toString()));
143
+ console.log(chalk.gray(' Active Streams: '), chalk.white('N/A')); // TODO
144
+ console.log(chalk.gray(' Investments: '), chalk.white('N/A')); // TODO
145
+ console.log();
146
+
147
+ // Balance Section
148
+ console.log(chalk.bold.underline('💰 BALANCES'));
149
+ console.log();
150
+ console.log(chalk.gray(' USDC: '), chalk.green.bold(usdcBalance), chalk.dim('USDC'));
151
+ console.log(chalk.gray(' ETH: '), chalk.blue(ethBalance), chalk.dim('ETH'));
152
+ console.log(chalk.gray(' Net Worth: '), chalk.bold.white(totalNetWorth.toFixed(2)), chalk.dim('USDC equiv'));
153
+ console.log();
154
+
155
+ console.log(chalk.cyan.bold('═══════════════════════════════════════════════════════════\n'));
156
+
157
+ // Quick actions
158
+ console.log(chalk.dim('Quick actions:'));
159
+ console.log(chalk.dim(' • Open dashboard: ') + chalk.green('plob dashboard'));
160
+ console.log(chalk.dim(' • Check health: ') + chalk.green('plob health'));
161
+ console.log(chalk.dim(' • View transactions:') + chalk.green('plob status'));
162
+ console.log();
163
+
164
+ } catch (err: any) {
165
+ spinner.stop();
166
+ error(`Failed to fetch profile: ${err.message}`);
167
+ process.exit(1);
168
+ }
169
+ });
170
+
171
+ return cmd;
172
+ }
package/src/index.ts CHANGED
@@ -21,6 +21,14 @@ import { createSwapCommand } from './commands/swap';
21
21
  import { createBridgeCommand } from './commands/bridge';
22
22
  import { createPortfolioCommand } from './commands/portfolio';
23
23
  import { createTreasuryCommand } from './commands/treasury';
24
+ import { registerInvestCommand } from './commands/invest';
25
+ import { createQuickstartCommand } from './commands/quickstart';
26
+ import { createWhoamiCommand } from './commands/whoami';
27
+ import { createDashboardCommand } from './commands/dashboard';
28
+ import { createHealthCommand } from './commands/health';
29
+ import { createSearchCommand } from './commands/search';
30
+ import { createExportCommand } from './commands/export';
31
+ import { createTrustGraphCommand } from './commands/trust-graph';
24
32
  import chalk from 'chalk';
25
33
 
26
34
  // Load environment variables from .env file if present
@@ -30,9 +38,9 @@ dotenv.config();
30
38
  const program = new Command();
31
39
 
32
40
  program
33
- .name('plob')
41
+ .name('paylobster')
34
42
  .description('🦞 PayLobster CLI - Payment infrastructure for AI agents')
35
- .version('4.3.0');
43
+ .version('4.5.0');
36
44
 
37
45
  // ASCII art banner
38
46
  const banner = `
@@ -68,6 +76,14 @@ program.addCommand(createSwapCommand());
68
76
  program.addCommand(createBridgeCommand());
69
77
  program.addCommand(createPortfolioCommand());
70
78
  program.addCommand(createTreasuryCommand());
79
+ program.addCommand(createQuickstartCommand());
80
+ program.addCommand(createWhoamiCommand());
81
+ program.addCommand(createDashboardCommand());
82
+ program.addCommand(createHealthCommand());
83
+ program.addCommand(createSearchCommand());
84
+ program.addCommand(createExportCommand());
85
+ program.addCommand(createTrustGraphCommand());
86
+ registerInvestCommand(program);
71
87
 
72
88
  // Handle errors
73
89
  program.exitOverride((err) => {
@@ -11,6 +11,7 @@ const CONTRACTS_MAINNET = {
11
11
  CREDIT: '0xD9241Ce8a721Ef5fcCAc5A11983addC526eC80E1' as Address,
12
12
  ESCROW: '0x49EdEe04c78B7FeD5248A20706c7a6c540748806' as Address,
13
13
  USDC: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' as Address,
14
+ TRUST_GRAPH: '0x0000000000000000000000000000000000000000' as Address, // TODO: Deploy TrustGraph
14
15
  };
15
16
 
16
17
  const CONTRACTS_SEPOLIA = {
@@ -21,6 +22,7 @@ const CONTRACTS_SEPOLIA = {
21
22
  CREDIT: '0xBA64e2b2F2a80D03A4B13b3396942C1e78205C7d' as Address,
22
23
  ESCROW: '0x78D1f50a1965dE34f6b5a3D3546C94FE1809Cd82' as Address,
23
24
  USDC: '0x036CbD53842c5426634e7929541eC2318f3dCF7e' as Address,
25
+ TRUST_GRAPH: '0x0000000000000000000000000000000000000000' as Address, // TODO: Deploy TrustGraph
24
26
  };
25
27
 
26
28
  // ABIs
@@ -390,3 +392,160 @@ export function formatUSDC(amount: bigint): string {
390
392
  export function formatETH(amount: bigint): string {
391
393
  return formatUnits(amount, 18);
392
394
  }
395
+
396
+ // TrustGraph ABI
397
+ const TRUST_GRAPH_ABI = [
398
+ {
399
+ inputs: [
400
+ { name: 'agent', type: 'address' },
401
+ { name: 'trustLevel', type: 'uint8' },
402
+ ],
403
+ name: 'endorseAgent',
404
+ outputs: [],
405
+ stateMutability: 'nonpayable',
406
+ type: 'function',
407
+ },
408
+ {
409
+ inputs: [{ name: 'agent', type: 'address' }],
410
+ name: 'revokeEndorsement',
411
+ outputs: [],
412
+ stateMutability: 'nonpayable',
413
+ type: 'function',
414
+ },
415
+ {
416
+ inputs: [
417
+ { name: 'from', type: 'address' },
418
+ { name: 'to', type: 'address' },
419
+ ],
420
+ name: 'getDirectTrust',
421
+ outputs: [{ name: 'trustLevel', type: 'uint8' }],
422
+ stateMutability: 'view',
423
+ type: 'function',
424
+ },
425
+ {
426
+ inputs: [
427
+ { name: 'from', type: 'address' },
428
+ { name: 'to', type: 'address' },
429
+ { name: 'maxDepth', type: 'uint8' },
430
+ ],
431
+ name: 'getInferredTrust',
432
+ outputs: [
433
+ { name: 'trustScore', type: 'uint256' },
434
+ { name: 'pathLength', type: 'uint8' },
435
+ ],
436
+ stateMutability: 'view',
437
+ type: 'function',
438
+ },
439
+ {
440
+ inputs: [{ name: 'agent', type: 'address' }],
441
+ name: 'getEndorsements',
442
+ outputs: [{ name: 'endorsed', type: 'address[]' }],
443
+ stateMutability: 'view',
444
+ type: 'function',
445
+ },
446
+ {
447
+ inputs: [{ name: 'agent', type: 'address' }],
448
+ name: 'getEndorsers',
449
+ outputs: [{ name: 'endorsers', type: 'address[]' }],
450
+ stateMutability: 'view',
451
+ type: 'function',
452
+ },
453
+ {
454
+ inputs: [{ name: 'agent', type: 'address' }],
455
+ name: 'getTrustScore',
456
+ outputs: [{ name: 'score', type: 'uint256' }],
457
+ stateMutability: 'view',
458
+ type: 'function',
459
+ },
460
+ ] as const;
461
+
462
+ /**
463
+ * Get TrustGraph module instance
464
+ */
465
+ export function getTrustGraph() {
466
+ const config = loadConfig();
467
+ const publicClient = getPublicClient(config.network);
468
+ const contracts = getContracts(config.network);
469
+ const chain = config.network === 'mainnet' ? base : baseSepolia;
470
+
471
+ return {
472
+ async endorseAgent(agent: Address, trustLevel: number) {
473
+ const { client, account } = await loadWallet();
474
+ const hash = await client.writeContract({
475
+ address: contracts.TRUST_GRAPH,
476
+ abi: TRUST_GRAPH_ABI,
477
+ functionName: 'endorseAgent',
478
+ args: [agent, trustLevel],
479
+ account,
480
+ chain,
481
+ });
482
+ return hash;
483
+ },
484
+
485
+ async revokeEndorsement(agent: Address) {
486
+ const { client, account } = await loadWallet();
487
+ const hash = await client.writeContract({
488
+ address: contracts.TRUST_GRAPH,
489
+ abi: TRUST_GRAPH_ABI,
490
+ functionName: 'revokeEndorsement',
491
+ args: [agent],
492
+ account,
493
+ chain,
494
+ });
495
+ return hash;
496
+ },
497
+
498
+ async getDirectTrust(from: Address, to: Address): Promise<number> {
499
+ const result = await publicClient.readContract({
500
+ address: contracts.TRUST_GRAPH,
501
+ abi: TRUST_GRAPH_ABI,
502
+ functionName: 'getDirectTrust',
503
+ args: [from, to],
504
+ });
505
+ return Number(result);
506
+ },
507
+
508
+ async getInferredTrust(from: Address, to: Address, maxDepth: number = 4) {
509
+ const result = await publicClient.readContract({
510
+ address: contracts.TRUST_GRAPH,
511
+ abi: TRUST_GRAPH_ABI,
512
+ functionName: 'getInferredTrust',
513
+ args: [from, to, maxDepth],
514
+ });
515
+ return {
516
+ trustScore: Number(result[0]),
517
+ pathLength: Number(result[1]),
518
+ };
519
+ },
520
+
521
+ async getEndorsements(agent: Address): Promise<Address[]> {
522
+ const result = await publicClient.readContract({
523
+ address: contracts.TRUST_GRAPH,
524
+ abi: TRUST_GRAPH_ABI,
525
+ functionName: 'getEndorsements',
526
+ args: [agent],
527
+ });
528
+ return result as Address[];
529
+ },
530
+
531
+ async getEndorsers(agent: Address): Promise<Address[]> {
532
+ const result = await publicClient.readContract({
533
+ address: contracts.TRUST_GRAPH,
534
+ abi: TRUST_GRAPH_ABI,
535
+ functionName: 'getEndorsers',
536
+ args: [agent],
537
+ });
538
+ return result as Address[];
539
+ },
540
+
541
+ async getAggregateTrust(agent: Address): Promise<number> {
542
+ const result = await publicClient.readContract({
543
+ address: contracts.TRUST_GRAPH,
544
+ abi: TRUST_GRAPH_ABI,
545
+ functionName: 'getTrustScore',
546
+ args: [agent],
547
+ });
548
+ return Number(result);
549
+ },
550
+ };
551
+ }