@paylobster/cli 4.3.0 → 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.
- package/README.md +82 -40
- package/dist/src/commands/dashboard.d.ts +3 -0
- package/dist/src/commands/dashboard.d.ts.map +1 -0
- package/dist/src/commands/dashboard.js +67 -0
- package/dist/src/commands/dashboard.js.map +1 -0
- package/dist/src/commands/export.d.ts +3 -0
- package/dist/src/commands/export.d.ts.map +1 -0
- package/dist/src/commands/export.js +97 -0
- package/dist/src/commands/export.js.map +1 -0
- package/dist/src/commands/health.d.ts +3 -0
- package/dist/src/commands/health.d.ts.map +1 -0
- package/dist/src/commands/health.js +165 -0
- package/dist/src/commands/health.js.map +1 -0
- package/dist/src/commands/invest.d.ts +3 -0
- package/dist/src/commands/invest.d.ts.map +1 -0
- package/dist/src/commands/invest.js +721 -0
- package/dist/src/commands/invest.js.map +1 -0
- package/dist/src/commands/quickstart.d.ts +3 -0
- package/dist/src/commands/quickstart.d.ts.map +1 -0
- package/dist/src/commands/quickstart.js +138 -0
- package/dist/src/commands/quickstart.js.map +1 -0
- package/dist/src/commands/search.d.ts +3 -0
- package/dist/src/commands/search.d.ts.map +1 -0
- package/dist/src/commands/search.js +126 -0
- package/dist/src/commands/search.js.map +1 -0
- package/dist/src/commands/treasury.d.ts.map +1 -1
- package/dist/src/commands/treasury.js +317 -0
- package/dist/src/commands/treasury.js.map +1 -1
- package/dist/src/commands/trust-graph.d.ts +3 -0
- package/dist/src/commands/trust-graph.d.ts.map +1 -0
- package/dist/src/commands/trust-graph.js +282 -0
- package/dist/src/commands/trust-graph.js.map +1 -0
- package/dist/src/commands/whoami.d.ts +3 -0
- package/dist/src/commands/whoami.d.ts.map +1 -0
- package/dist/src/commands/whoami.js +160 -0
- package/dist/src/commands/whoami.js.map +1 -0
- package/dist/src/index.js +18 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/lib/contracts.d.ts +177 -23
- package/dist/src/lib/contracts.d.ts.map +1 -1
- package/dist/src/lib/contracts.js +151 -0
- package/dist/src/lib/contracts.js.map +1 -1
- package/package.json +4 -2
- package/src/commands/dashboard.ts +69 -0
- package/src/commands/export.ts +132 -0
- package/src/commands/health.ts +212 -0
- package/src/commands/invest.ts +810 -0
- package/src/commands/quickstart.ts +150 -0
- package/src/commands/search.ts +151 -0
- package/src/commands/treasury.ts +385 -0
- package/src/commands/trust-graph.ts +267 -0
- package/src/commands/whoami.ts +172 -0
- package/src/index.ts +18 -2
- package/src/lib/contracts.ts +159 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { getTrustGraph } from '../lib/contracts';
|
|
3
|
+
import { error, success, outputJSON, header, info } from '../lib/display';
|
|
4
|
+
import type { OutputOptions } from '../lib/types';
|
|
5
|
+
import type { Address } from 'viem';
|
|
6
|
+
|
|
7
|
+
export function createTrustGraphCommand(): Command {
|
|
8
|
+
const cmd = new Command('trust')
|
|
9
|
+
.description('Manage and query trust network')
|
|
10
|
+
.addHelpText('after', `
|
|
11
|
+
Examples:
|
|
12
|
+
$ plob trust endorse 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb 85
|
|
13
|
+
$ plob trust revoke 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb
|
|
14
|
+
$ plob trust check 0xAlice 0xBob
|
|
15
|
+
$ plob trust score 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb
|
|
16
|
+
$ plob trust endorsements 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb
|
|
17
|
+
`);
|
|
18
|
+
|
|
19
|
+
// Endorse agent
|
|
20
|
+
cmd
|
|
21
|
+
.command('endorse')
|
|
22
|
+
.description('Endorse another agent with a trust level')
|
|
23
|
+
.argument('<address>', 'Agent address to endorse')
|
|
24
|
+
.argument('<score>', 'Trust score (1-100)')
|
|
25
|
+
.option('--json', 'Output as JSON')
|
|
26
|
+
.action(async (addressArg: string, scoreArg: string, options: OutputOptions) => {
|
|
27
|
+
try {
|
|
28
|
+
const address = addressArg as Address;
|
|
29
|
+
const score = parseInt(scoreArg);
|
|
30
|
+
|
|
31
|
+
if (score < 1 || score > 100) {
|
|
32
|
+
error('Trust score must be between 1 and 100');
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const trustGraph = getTrustGraph();
|
|
37
|
+
|
|
38
|
+
info(`Endorsing ${address} with trust level ${score}...`);
|
|
39
|
+
const hash = await trustGraph.endorseAgent(address, score);
|
|
40
|
+
|
|
41
|
+
if (outputJSON({ transactionHash: hash, endorsed: address, trustLevel: score }, options)) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
success(`Endorsed ${address} with trust level ${score}/100`);
|
|
46
|
+
console.log(`Transaction: ${hash}`);
|
|
47
|
+
} catch (err) {
|
|
48
|
+
error(`Failed to endorse agent: ${err}`);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Revoke endorsement
|
|
54
|
+
cmd
|
|
55
|
+
.command('revoke')
|
|
56
|
+
.description('Revoke an endorsement')
|
|
57
|
+
.argument('<address>', 'Agent address to revoke endorsement from')
|
|
58
|
+
.option('--json', 'Output as JSON')
|
|
59
|
+
.action(async (addressArg: string, options: OutputOptions) => {
|
|
60
|
+
try {
|
|
61
|
+
const address = addressArg as Address;
|
|
62
|
+
const trustGraph = getTrustGraph();
|
|
63
|
+
|
|
64
|
+
info(`Revoking endorsement of ${address}...`);
|
|
65
|
+
const hash = await trustGraph.revokeEndorsement(address);
|
|
66
|
+
|
|
67
|
+
if (outputJSON({ transactionHash: hash, revoked: address }, options)) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
success(`Revoked endorsement of ${address}`);
|
|
72
|
+
console.log(`Transaction: ${hash}`);
|
|
73
|
+
} catch (err) {
|
|
74
|
+
error(`Failed to revoke endorsement: ${err}`);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// Check trust between two agents
|
|
80
|
+
cmd
|
|
81
|
+
.command('check')
|
|
82
|
+
.description('Check trust level between two agents')
|
|
83
|
+
.argument('<from>', 'Source agent address')
|
|
84
|
+
.argument('<to>', 'Target agent address')
|
|
85
|
+
.option('--inferred', 'Calculate inferred trust through network')
|
|
86
|
+
.option('--depth <number>', 'Max hops for inferred trust (default: 4)', '4')
|
|
87
|
+
.option('--json', 'Output as JSON')
|
|
88
|
+
.action(async (fromArg: string, toArg: string, options: any) => {
|
|
89
|
+
try {
|
|
90
|
+
const from = fromArg as Address;
|
|
91
|
+
const to = toArg as Address;
|
|
92
|
+
const trustGraph = getTrustGraph();
|
|
93
|
+
|
|
94
|
+
if (options.inferred) {
|
|
95
|
+
// Get inferred trust through network
|
|
96
|
+
const maxDepth = parseInt(options.depth);
|
|
97
|
+
const result = await trustGraph.getInferredTrust(from, to, maxDepth);
|
|
98
|
+
|
|
99
|
+
if (outputJSON({ from, to, trustScore: result.trustScore, pathLength: result.pathLength, type: 'inferred' }, options)) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
header('Inferred Trust');
|
|
104
|
+
console.log();
|
|
105
|
+
console.log('From: ', from);
|
|
106
|
+
console.log('To: ', to);
|
|
107
|
+
console.log('Trust Score: ', result.trustScore);
|
|
108
|
+
console.log('Path Length: ', result.pathLength, 'hops');
|
|
109
|
+
console.log();
|
|
110
|
+
} else {
|
|
111
|
+
// Get direct trust
|
|
112
|
+
const trustLevel = await trustGraph.getDirectTrust(from, to);
|
|
113
|
+
|
|
114
|
+
if (outputJSON({ from, to, trustLevel, type: 'direct' }, options)) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
header('Direct Trust');
|
|
119
|
+
console.log();
|
|
120
|
+
console.log('From: ', from);
|
|
121
|
+
console.log('To: ', to);
|
|
122
|
+
console.log('Trust Level: ', trustLevel === 0 ? 'No direct endorsement' : `${trustLevel}/100`);
|
|
123
|
+
console.log();
|
|
124
|
+
}
|
|
125
|
+
} catch (err) {
|
|
126
|
+
error(`Failed to check trust: ${err}`);
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// Get aggregate trust score
|
|
132
|
+
cmd
|
|
133
|
+
.command('score')
|
|
134
|
+
.description('Get aggregate trust score for an agent')
|
|
135
|
+
.argument('<address>', 'Agent address')
|
|
136
|
+
.option('--json', 'Output as JSON')
|
|
137
|
+
.action(async (addressArg: string, options: OutputOptions) => {
|
|
138
|
+
try {
|
|
139
|
+
const address = addressArg as Address;
|
|
140
|
+
const trustGraph = getTrustGraph();
|
|
141
|
+
|
|
142
|
+
const [aggregateScore, endorsers] = await Promise.all([
|
|
143
|
+
trustGraph.getAggregateTrust(address),
|
|
144
|
+
trustGraph.getEndorsers(address),
|
|
145
|
+
]);
|
|
146
|
+
|
|
147
|
+
if (outputJSON({ address, aggregateScore, endorserCount: endorsers.length }, options)) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
header('Trust Score');
|
|
152
|
+
console.log();
|
|
153
|
+
console.log('Agent: ', address);
|
|
154
|
+
console.log('Aggregate Score: ', aggregateScore);
|
|
155
|
+
console.log('Endorser Count: ', endorsers.length);
|
|
156
|
+
console.log();
|
|
157
|
+
|
|
158
|
+
if (aggregateScore >= 80) {
|
|
159
|
+
console.log('✅ Highly trusted in the network');
|
|
160
|
+
} else if (aggregateScore >= 60) {
|
|
161
|
+
console.log('✅ Well trusted in the network');
|
|
162
|
+
} else if (aggregateScore >= 40) {
|
|
163
|
+
console.log('⚠️ Moderately trusted');
|
|
164
|
+
} else if (aggregateScore > 0) {
|
|
165
|
+
console.log('⚠️ Limited trust in the network');
|
|
166
|
+
} else {
|
|
167
|
+
console.log('❌ No endorsements yet');
|
|
168
|
+
}
|
|
169
|
+
console.log();
|
|
170
|
+
} catch (err) {
|
|
171
|
+
error(`Failed to get trust score: ${err}`);
|
|
172
|
+
process.exit(1);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// Get endorsements (agents this address has endorsed)
|
|
177
|
+
cmd
|
|
178
|
+
.command('endorsements')
|
|
179
|
+
.description('List all agents endorsed by an address')
|
|
180
|
+
.argument('[address]', 'Agent address (default: your wallet)')
|
|
181
|
+
.option('--json', 'Output as JSON')
|
|
182
|
+
.action(async (addressArg: string | undefined, options: OutputOptions) => {
|
|
183
|
+
try {
|
|
184
|
+
let address: Address;
|
|
185
|
+
|
|
186
|
+
if (addressArg) {
|
|
187
|
+
address = addressArg as Address;
|
|
188
|
+
} else {
|
|
189
|
+
const { getWalletAddress } = await import('../lib/wallet');
|
|
190
|
+
address = getWalletAddress() as Address;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const trustGraph = getTrustGraph();
|
|
194
|
+
const endorsed = await trustGraph.getEndorsements(address);
|
|
195
|
+
|
|
196
|
+
if (outputJSON({ address, endorsed, count: endorsed.length }, options)) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
header('Endorsements');
|
|
201
|
+
console.log();
|
|
202
|
+
console.log('Endorser: ', address);
|
|
203
|
+
console.log('Endorsed: ', endorsed.length, 'agents');
|
|
204
|
+
console.log();
|
|
205
|
+
|
|
206
|
+
if (endorsed.length > 0) {
|
|
207
|
+
endorsed.forEach((agent, i) => {
|
|
208
|
+
console.log(` ${i + 1}. ${agent}`);
|
|
209
|
+
});
|
|
210
|
+
console.log();
|
|
211
|
+
} else {
|
|
212
|
+
console.log('No endorsements yet.');
|
|
213
|
+
console.log();
|
|
214
|
+
}
|
|
215
|
+
} catch (err) {
|
|
216
|
+
error(`Failed to get endorsements: ${err}`);
|
|
217
|
+
process.exit(1);
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
// Get endorsers (agents who endorse this address)
|
|
222
|
+
cmd
|
|
223
|
+
.command('endorsers')
|
|
224
|
+
.description('List all agents who endorse an address')
|
|
225
|
+
.argument('[address]', 'Agent address (default: your wallet)')
|
|
226
|
+
.option('--json', 'Output as JSON')
|
|
227
|
+
.action(async (addressArg: string | undefined, options: OutputOptions) => {
|
|
228
|
+
try {
|
|
229
|
+
let address: Address;
|
|
230
|
+
|
|
231
|
+
if (addressArg) {
|
|
232
|
+
address = addressArg as Address;
|
|
233
|
+
} else {
|
|
234
|
+
const { getWalletAddress } = await import('../lib/wallet');
|
|
235
|
+
address = getWalletAddress() as Address;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const trustGraph = getTrustGraph();
|
|
239
|
+
const endorsers = await trustGraph.getEndorsers(address);
|
|
240
|
+
|
|
241
|
+
if (outputJSON({ address, endorsers, count: endorsers.length }, options)) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
header('Endorsers');
|
|
246
|
+
console.log();
|
|
247
|
+
console.log('Endorsed: ', address);
|
|
248
|
+
console.log('Endorsers: ', endorsers.length, 'agents');
|
|
249
|
+
console.log();
|
|
250
|
+
|
|
251
|
+
if (endorsers.length > 0) {
|
|
252
|
+
endorsers.forEach((agent, i) => {
|
|
253
|
+
console.log(` ${i + 1}. ${agent}`);
|
|
254
|
+
});
|
|
255
|
+
console.log();
|
|
256
|
+
} else {
|
|
257
|
+
console.log('No endorsers yet.');
|
|
258
|
+
console.log();
|
|
259
|
+
}
|
|
260
|
+
} catch (err) {
|
|
261
|
+
error(`Failed to get endorsers: ${err}`);
|
|
262
|
+
process.exit(1);
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
return cmd;
|
|
267
|
+
}
|
|
@@ -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('
|
|
41
|
+
.name('paylobster')
|
|
34
42
|
.description('🦞 PayLobster CLI - Payment infrastructure for AI agents')
|
|
35
|
-
.version('4.
|
|
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) => {
|
package/src/lib/contracts.ts
CHANGED
|
@@ -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
|
+
}
|