@paylobster/cli 4.6.0 → 4.6.1

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 (38) hide show
  1. package/dist/src/commands/alerts.d.ts +3 -0
  2. package/dist/src/commands/alerts.d.ts.map +1 -0
  3. package/dist/src/commands/alerts.js +181 -0
  4. package/dist/src/commands/alerts.js.map +1 -0
  5. package/dist/src/commands/init.d.ts +3 -0
  6. package/dist/src/commands/init.d.ts.map +1 -0
  7. package/dist/src/commands/init.js +232 -0
  8. package/dist/src/commands/init.js.map +1 -0
  9. package/dist/src/commands/link.d.ts +6 -0
  10. package/dist/src/commands/link.d.ts.map +1 -0
  11. package/dist/src/commands/link.js +188 -0
  12. package/dist/src/commands/link.js.map +1 -0
  13. package/dist/src/commands/refund.d.ts +6 -0
  14. package/dist/src/commands/refund.d.ts.map +1 -0
  15. package/dist/src/commands/refund.js +199 -0
  16. package/dist/src/commands/refund.js.map +1 -0
  17. package/dist/src/commands/swap.d.ts.map +1 -1
  18. package/dist/src/commands/swap.js +93 -1
  19. package/dist/src/commands/swap.js.map +1 -1
  20. package/dist/src/commands/webhook.d.ts +6 -0
  21. package/dist/src/commands/webhook.d.ts.map +1 -0
  22. package/dist/src/commands/webhook.js +208 -0
  23. package/dist/src/commands/webhook.js.map +1 -0
  24. package/dist/src/index.js +10 -0
  25. package/dist/src/index.js.map +1 -1
  26. package/dist/src/lib/contracts.d.ts +23 -161
  27. package/dist/src/lib/contracts.d.ts.map +1 -1
  28. package/dist/src/lib/contracts.js +6 -6
  29. package/dist/src/lib/contracts.js.map +1 -1
  30. package/package.json +1 -1
  31. package/src/commands/alerts.ts +210 -0
  32. package/src/commands/init.ts +256 -0
  33. package/src/commands/link.ts +240 -0
  34. package/src/commands/refund.ts +250 -0
  35. package/src/commands/swap.ts +120 -1
  36. package/src/commands/webhook.ts +260 -0
  37. package/src/index.ts +10 -0
  38. package/src/lib/contracts.ts +6 -6
@@ -0,0 +1,250 @@
1
+ import { Command } from 'commander';
2
+ import { success, error, info, withSpinner, outputJSON, confirm } from '../lib/display';
3
+ import type { OutputOptions } from '../lib/types';
4
+
5
+ const API_URL = process.env.PAYLOBSTER_API_URL || 'https://paylobster.com';
6
+
7
+ interface Refund {
8
+ refundId: string;
9
+ escrowId: number;
10
+ status: 'pending' | 'approved' | 'rejected' | 'processed';
11
+ amount: string;
12
+ reason: string;
13
+ txHash?: string;
14
+ auto?: boolean;
15
+ createdAt: string;
16
+ processedAt?: string;
17
+ }
18
+
19
+ /**
20
+ * Refunds command
21
+ */
22
+ export function createRefundCommand(): Command {
23
+ const cmd = new Command('refund')
24
+ .description('Request and manage refunds');
25
+
26
+ // Request subcommand
27
+ cmd
28
+ .command('request')
29
+ .description('Request a refund for an escrow')
30
+ .requiredOption('--escrow-id <id>', 'Escrow ID')
31
+ .requiredOption('--reason <text>', 'Reason for refund')
32
+ .option('--tx-hash <hash>', 'Transaction hash (if applicable)')
33
+ .option('--yes', 'Skip confirmation')
34
+ .option('--json', 'Output as JSON')
35
+ .action(async (options: {
36
+ escrowId: string;
37
+ reason: string;
38
+ txHash?: string;
39
+ yes?: boolean;
40
+ } & OutputOptions) => {
41
+ try {
42
+ // Validate escrow ID
43
+ const escrowId = parseInt(options.escrowId);
44
+ if (isNaN(escrowId) || escrowId < 0) {
45
+ error('Invalid escrow ID. Must be a non-negative number');
46
+ process.exit(1);
47
+ }
48
+
49
+ // Confirm refund request
50
+ if (!options.yes) {
51
+ console.log();
52
+ console.log('Refund Request:');
53
+ console.log(' Escrow ID: ', escrowId);
54
+ console.log(' Reason: ', options.reason);
55
+ console.log();
56
+
57
+ const confirmed = await confirm('Submit this refund request?');
58
+ if (!confirmed) {
59
+ info('Cancelled');
60
+ process.exit(0);
61
+ }
62
+ }
63
+
64
+ const refund = await withSpinner(
65
+ 'Submitting refund request...',
66
+ async () => {
67
+ const response = await fetch(`${API_URL}/api/v3/refunds`, {
68
+ method: 'POST',
69
+ headers: {
70
+ 'Content-Type': 'application/json',
71
+ },
72
+ body: JSON.stringify({
73
+ escrowId,
74
+ reason: options.reason,
75
+ txHash: options.txHash,
76
+ }),
77
+ });
78
+
79
+ if (!response.ok) {
80
+ const err = await response.json() as { error?: string };
81
+ throw new Error(err.error || 'Failed to request refund');
82
+ }
83
+
84
+ return response.json() as Promise<Refund>;
85
+ }
86
+ );
87
+
88
+ if (outputJSON(refund, options)) {
89
+ return;
90
+ }
91
+
92
+ success('Refund request submitted!');
93
+ console.log();
94
+ console.log(' Refund ID: ', refund.refundId);
95
+ console.log(' Escrow ID: ', refund.escrowId);
96
+ console.log(' Status: ', getStatusEmoji(refund.status), refund.status);
97
+ console.log(' Amount: ', refund.amount);
98
+ console.log(' Reason: ', refund.reason);
99
+ console.log(' Created: ', new Date(refund.createdAt).toLocaleString());
100
+ console.log();
101
+ info('Your refund request will be processed according to the escrow terms');
102
+ } catch (err) {
103
+ error(`Failed to request refund: ${(err as Error).message}`);
104
+ process.exit(1);
105
+ }
106
+ });
107
+
108
+ // Get subcommand
109
+ cmd
110
+ .command('get <refund-id>')
111
+ .description('Get refund status')
112
+ .option('--json', 'Output as JSON')
113
+ .action(async (refundId: string, options: OutputOptions) => {
114
+ try {
115
+ const refund = await withSpinner(
116
+ 'Fetching refund details...',
117
+ async () => {
118
+ const response = await fetch(
119
+ `${API_URL}/api/v3/refunds?refundId=${encodeURIComponent(refundId)}`,
120
+ {
121
+ method: 'GET',
122
+ headers: {
123
+ 'Content-Type': 'application/json',
124
+ },
125
+ }
126
+ );
127
+
128
+ if (!response.ok) {
129
+ const err = await response.json() as { error?: string };
130
+ throw new Error(err.error || 'Failed to fetch refund');
131
+ }
132
+
133
+ return response.json() as Promise<Refund>;
134
+ }
135
+ );
136
+
137
+ if (outputJSON(refund, options)) {
138
+ return;
139
+ }
140
+
141
+ console.log();
142
+ console.log('Refund Details:');
143
+ console.log(' Refund ID: ', refund.refundId);
144
+ console.log(' Escrow ID: ', refund.escrowId);
145
+ console.log(' Status: ', getStatusEmoji(refund.status), refund.status);
146
+ console.log(' Amount: ', refund.amount);
147
+ console.log(' Reason: ', refund.reason);
148
+ if (refund.auto) {
149
+ console.log(' Auto: ', '✅ Automatic refund');
150
+ }
151
+ if (refund.txHash) {
152
+ console.log(' TX Hash: ', refund.txHash);
153
+ }
154
+ console.log(' Created: ', new Date(refund.createdAt).toLocaleString());
155
+ if (refund.processedAt) {
156
+ console.log(' Processed: ', new Date(refund.processedAt).toLocaleString());
157
+ }
158
+ console.log();
159
+ } catch (err) {
160
+ error(`Failed to fetch refund: ${(err as Error).message}`);
161
+ process.exit(1);
162
+ }
163
+ });
164
+
165
+ // List by escrow subcommand
166
+ cmd
167
+ .command('list <escrow-id>')
168
+ .description('List all refunds for an escrow')
169
+ .option('--json', 'Output as JSON')
170
+ .action(async (escrowIdStr: string, options: OutputOptions) => {
171
+ try {
172
+ // Validate escrow ID
173
+ const escrowId = parseInt(escrowIdStr);
174
+ if (isNaN(escrowId) || escrowId < 0) {
175
+ error('Invalid escrow ID. Must be a non-negative number');
176
+ process.exit(1);
177
+ }
178
+
179
+ const result = await withSpinner(
180
+ 'Fetching refunds...',
181
+ async () => {
182
+ const response = await fetch(
183
+ `${API_URL}/api/v3/refunds?escrowId=${escrowId}`,
184
+ {
185
+ method: 'GET',
186
+ headers: {
187
+ 'Content-Type': 'application/json',
188
+ },
189
+ }
190
+ );
191
+
192
+ if (!response.ok) {
193
+ const err = await response.json() as { error?: string };
194
+ throw new Error(err.error || 'Failed to fetch refunds');
195
+ }
196
+
197
+ return response.json() as Promise<{ escrowId: number; refunds: Refund[] }>;
198
+ }
199
+ );
200
+
201
+ if (outputJSON(result, options)) {
202
+ return;
203
+ }
204
+
205
+ if (result.refunds.length === 0) {
206
+ info(`No refunds found for escrow ID ${escrowId}`);
207
+ return;
208
+ }
209
+
210
+ console.log();
211
+ console.log(`Found ${result.refunds.length} refund(s) for escrow ${escrowId}:`);
212
+ console.log();
213
+
214
+ for (const refund of result.refunds) {
215
+ console.log(` ${refund.refundId}`);
216
+ console.log(` Status: ${getStatusEmoji(refund.status)} ${refund.status}`);
217
+ console.log(` Amount: ${refund.amount}`);
218
+ console.log(` Reason: ${refund.reason}`);
219
+ if (refund.auto) {
220
+ console.log(` Auto: ✅ Automatic`);
221
+ }
222
+ console.log(` Created: ${new Date(refund.createdAt).toLocaleString()}`);
223
+ if (refund.processedAt) {
224
+ console.log(` Processed: ${new Date(refund.processedAt).toLocaleString()}`);
225
+ }
226
+ console.log();
227
+ }
228
+ } catch (err) {
229
+ error(`Failed to fetch refunds: ${(err as Error).message}`);
230
+ process.exit(1);
231
+ }
232
+ });
233
+
234
+ return cmd;
235
+ }
236
+
237
+ function getStatusEmoji(status: string): string {
238
+ switch (status) {
239
+ case 'pending':
240
+ return '⏳';
241
+ case 'approved':
242
+ return '✅';
243
+ case 'rejected':
244
+ return '❌';
245
+ case 'processed':
246
+ return '✅';
247
+ default:
248
+ return '❓';
249
+ }
250
+ }
@@ -155,12 +155,42 @@ async function getTokenPrice(tokenAddress: string): Promise<any> {
155
155
  return call0xAPI(endpoint);
156
156
  }
157
157
 
158
+ const API_BASE = process.env.PAYLOBSTER_API_URL || 'https://paylobster.com';
159
+
160
+ /**
161
+ * Get smart route from PayLobster API
162
+ */
163
+ async function getSmartRoute(
164
+ sellToken: string,
165
+ buyToken: string,
166
+ sellAmount: string,
167
+ takerAddress?: string
168
+ ): Promise<any> {
169
+ const res = await fetch(`${API_BASE}/api/v3/swap/route`, {
170
+ method: 'POST',
171
+ headers: { 'Content-Type': 'application/json' },
172
+ body: JSON.stringify({
173
+ tokenIn: sellToken,
174
+ tokenOut: buyToken,
175
+ amountIn: sellAmount,
176
+ takerAddress,
177
+ }),
178
+ });
179
+
180
+ if (!res.ok) {
181
+ const data = await res.json().catch(() => ({}));
182
+ throw new Error(data.error || `Smart route failed: ${res.status}`);
183
+ }
184
+
185
+ return res.json();
186
+ }
187
+
158
188
  /**
159
189
  * Create swap command
160
190
  */
161
191
  export function createSwapCommand(): Command {
162
192
  const cmd = new Command('swap')
163
- .description('Token swaps on Base using 0x');
193
+ .description('Token swaps on Base using 0x (with smart routing)');
164
194
 
165
195
  // Swap quote subcommand
166
196
  cmd
@@ -300,6 +330,95 @@ export function createSwapCommand(): Command {
300
330
  }
301
331
  });
302
332
 
333
+ // Smart swap subcommand (natural language style)
334
+ cmd
335
+ .command('auto')
336
+ .description('Smart swap with auto-routing (multi-hop if needed)')
337
+ .argument('<amount>', 'Amount to sell')
338
+ .argument('<fromToken>', 'Token to sell')
339
+ .argument('[toKeyword]', '"to" keyword (ignored)')
340
+ .argument('[toToken]', 'Token to buy')
341
+ .option('--usd', 'Interpret amount as USD value')
342
+ .option('--slippage <percent>', 'Slippage tolerance (default: 0.5)', '0.5')
343
+ .option('--yes', 'Skip confirmation')
344
+ .option('--json', 'Output as JSON')
345
+ .action(async (amount: string, fromTokenArg: string, toKeyword: string, toTokenArg: string, options: {
346
+ usd?: boolean;
347
+ slippage?: string;
348
+ yes?: boolean;
349
+ } & OutputOptions) => {
350
+ try {
351
+ const address = getWalletAddress() as `0x${string}`;
352
+
353
+ // Handle "10 USDC to ANTIHUNTER" pattern
354
+ let toToken = toTokenArg;
355
+ if (toKeyword && toKeyword.toLowerCase() !== 'to') {
356
+ // "swap auto 10 USDC ANTIHUNTER" — no "to" keyword
357
+ toToken = toKeyword;
358
+ }
359
+
360
+ if (!toToken) {
361
+ error('Missing destination token. Usage: paylobster swap auto 10 USDC to ANTIHUNTER');
362
+ process.exit(1);
363
+ }
364
+
365
+ const sellTokenAddr = resolveToken(fromTokenArg);
366
+ const buyTokenAddr = resolveToken(toToken);
367
+ const sellDecimals = getTokenDecimals(fromTokenArg);
368
+ const sellAmount = parseTokenAmount(amount.replace('$', ''), sellDecimals);
369
+
370
+ const routeData = await withSpinner(
371
+ '🧠 Finding best route...',
372
+ async () => getSmartRoute(sellTokenAddr, buyTokenAddr, sellAmount, address)
373
+ );
374
+
375
+ if (!routeData.bestRoute) {
376
+ error('No route found for this swap');
377
+ process.exit(1);
378
+ }
379
+
380
+ const route = routeData.bestRoute;
381
+ const hopCount = route.hops?.length || 1;
382
+
383
+ if (outputJSON(routeData, options)) return;
384
+
385
+ console.log();
386
+ console.log(chalk.bold.cyan('🧠 Smart Route Found'));
387
+ console.log();
388
+ console.log(' From: ', chalk.white.bold(amount), chalk.gray(fromTokenArg.toUpperCase()));
389
+ console.log(' To: ', chalk.white.bold(toToken.toUpperCase()));
390
+ console.log(' Route: ', chalk.white(route.source || 'Auto'));
391
+ console.log(' Hops: ', chalk.white(hopCount.toString()));
392
+
393
+ // Show each hop
394
+ if (route.hops) {
395
+ for (let i = 0; i < route.hops.length; i++) {
396
+ const hop = route.hops[i];
397
+ console.log(chalk.gray(` Step ${i + 1}: `), chalk.dim(`${hop.dex}: ${hop.tokenIn.slice(0, 8)}... → ${hop.tokenOut.slice(0, 8)}...`));
398
+ }
399
+ }
400
+
401
+ console.log(' Output: ', chalk.green.bold(routeData.estimatedOutput));
402
+ console.log(' Impact: ', chalk.yellow(`${((routeData.priceImpact || 0) * 100).toFixed(2)}%`));
403
+ console.log(' Gas: ', chalk.gray(`~${routeData.gasEstimate}`));
404
+ console.log();
405
+
406
+ if (!options.yes) {
407
+ const confirmed = await confirm('Execute this swap?');
408
+ if (!confirmed) {
409
+ info('Cancelled');
410
+ process.exit(0);
411
+ }
412
+ }
413
+
414
+ info('Swap execution requires wallet signing. Transaction data is available above.');
415
+ console.log();
416
+ } catch (err) {
417
+ error(`Smart swap failed: ${err}`);
418
+ process.exit(1);
419
+ }
420
+ });
421
+
303
422
  // List tokens subcommand
304
423
  cmd
305
424
  .command('tokens')
@@ -0,0 +1,260 @@
1
+ import { Command } from 'commander';
2
+ import { success, error, info, withSpinner, outputJSON } from '../lib/display';
3
+ import type { OutputOptions } from '../lib/types';
4
+
5
+ const API_URL = process.env.PAYLOBSTER_API_URL || 'https://paylobster.com';
6
+
7
+ interface Webhook {
8
+ id: string;
9
+ url: string;
10
+ events: string[];
11
+ secret?: string;
12
+ createdAt: string;
13
+ status: 'active' | 'paused';
14
+ lastDeliveryAttempt?: string;
15
+ lastDeliveryStatus?: 'success' | 'failed';
16
+ }
17
+
18
+ /**
19
+ * Webhooks command
20
+ */
21
+ export function createWebhookCommand(): Command {
22
+ const cmd = new Command('webhooks')
23
+ .description('Register and manage webhooks');
24
+
25
+ // Register subcommand
26
+ cmd
27
+ .command('register')
28
+ .description('Register a new webhook')
29
+ .requiredOption('--url <url>', 'Webhook URL')
30
+ .requiredOption('--events <events>', 'Comma-separated event types')
31
+ .option('--secret <secret>', 'Webhook secret for signature verification')
32
+ .option('--json', 'Output as JSON')
33
+ .action(async (options: {
34
+ url: string;
35
+ events: string;
36
+ secret?: string;
37
+ } & OutputOptions) => {
38
+ try {
39
+ // Validate URL
40
+ try {
41
+ new URL(options.url);
42
+ } catch {
43
+ error('Invalid URL format');
44
+ process.exit(1);
45
+ }
46
+
47
+ // Parse events
48
+ const events = options.events.split(',').map(e => e.trim()).filter(Boolean);
49
+ if (events.length === 0) {
50
+ error('At least one event type is required');
51
+ process.exit(1);
52
+ }
53
+
54
+ const webhook = await withSpinner(
55
+ 'Registering webhook...',
56
+ async () => {
57
+ const response = await fetch(`${API_URL}/api/v3/webhooks`, {
58
+ method: 'POST',
59
+ headers: {
60
+ 'Content-Type': 'application/json',
61
+ },
62
+ body: JSON.stringify({
63
+ url: options.url,
64
+ events,
65
+ secret: options.secret,
66
+ }),
67
+ });
68
+
69
+ if (!response.ok) {
70
+ const err = await response.json() as { error?: string };
71
+ throw new Error(err.error || 'Failed to register webhook');
72
+ }
73
+
74
+ return response.json() as Promise<Webhook>;
75
+ }
76
+ );
77
+
78
+ if (outputJSON(webhook, options)) {
79
+ return;
80
+ }
81
+
82
+ success('Webhook registered!');
83
+ console.log();
84
+ console.log(' Webhook ID: ', webhook.id);
85
+ console.log(' URL: ', webhook.url);
86
+ console.log(' Events: ', webhook.events.join(', '));
87
+ console.log(' Status: ', webhook.status);
88
+ if (webhook.secret) {
89
+ console.log(' Secret: ', webhook.secret);
90
+ }
91
+ console.log();
92
+ info('Your webhook will receive notifications for the specified events');
93
+ } catch (err) {
94
+ error(`Failed to register webhook: ${(err as Error).message}`);
95
+ process.exit(1);
96
+ }
97
+ });
98
+
99
+ // List subcommand
100
+ cmd
101
+ .command('list')
102
+ .description('List all registered webhooks')
103
+ .option('--address <address>', 'Filter by address')
104
+ .option('--json', 'Output as JSON')
105
+ .action(async (options: {
106
+ address?: string;
107
+ } & OutputOptions) => {
108
+ try {
109
+ const result = await withSpinner(
110
+ 'Fetching webhooks...',
111
+ async () => {
112
+ const url = new URL(`${API_URL}/api/v3/webhooks`);
113
+ if (options.address) {
114
+ url.searchParams.set('address', options.address);
115
+ }
116
+
117
+ const response = await fetch(url.toString(), {
118
+ method: 'GET',
119
+ headers: {
120
+ 'Content-Type': 'application/json',
121
+ },
122
+ });
123
+
124
+ if (!response.ok) {
125
+ const err = await response.json() as { error?: string };
126
+ throw new Error(err.error || 'Failed to fetch webhooks');
127
+ }
128
+
129
+ return response.json() as Promise<{ webhooks: Webhook[] }>;
130
+ }
131
+ );
132
+
133
+ if (outputJSON(result, options)) {
134
+ return;
135
+ }
136
+
137
+ if (result.webhooks.length === 0) {
138
+ info('No webhooks registered');
139
+ return;
140
+ }
141
+
142
+ console.log();
143
+ console.log(`Found ${result.webhooks.length} webhook(s):`);
144
+ console.log();
145
+
146
+ for (const webhook of result.webhooks) {
147
+ console.log(` ${webhook.id}`);
148
+ console.log(` URL: ${webhook.url}`);
149
+ console.log(` Events: ${webhook.events.join(', ')}`);
150
+ console.log(` Status: ${webhook.status === 'active' ? '✅ Active' : '⏸️ Paused'}`);
151
+ if (webhook.lastDeliveryAttempt) {
152
+ const status = webhook.lastDeliveryStatus === 'success' ? '✅' : '❌';
153
+ console.log(` Last: ${status} ${new Date(webhook.lastDeliveryAttempt).toLocaleString()}`);
154
+ }
155
+ console.log();
156
+ }
157
+ } catch (err) {
158
+ error(`Failed to fetch webhooks: ${(err as Error).message}`);
159
+ process.exit(1);
160
+ }
161
+ });
162
+
163
+ // Get subcommand
164
+ cmd
165
+ .command('get <id>')
166
+ .description('Get webhook details')
167
+ .option('--include-secret', 'Include webhook secret in output')
168
+ .option('--json', 'Output as JSON')
169
+ .action(async (id: string, options: {
170
+ includeSecret?: boolean;
171
+ } & OutputOptions) => {
172
+ try {
173
+ const webhook = await withSpinner(
174
+ 'Fetching webhook...',
175
+ async () => {
176
+ const url = new URL(`${API_URL}/api/v3/webhooks/${id}`);
177
+ if (options.includeSecret) {
178
+ url.searchParams.set('includeSecret', 'true');
179
+ }
180
+
181
+ const response = await fetch(url.toString(), {
182
+ method: 'GET',
183
+ headers: {
184
+ 'Content-Type': 'application/json',
185
+ },
186
+ });
187
+
188
+ if (!response.ok) {
189
+ const err = await response.json() as { error?: string };
190
+ throw new Error(err.error || 'Failed to fetch webhook');
191
+ }
192
+
193
+ return response.json() as Promise<Webhook>;
194
+ }
195
+ );
196
+
197
+ if (outputJSON(webhook, options)) {
198
+ return;
199
+ }
200
+
201
+ console.log();
202
+ console.log('Webhook Details:');
203
+ console.log(' ID: ', webhook.id);
204
+ console.log(' URL: ', webhook.url);
205
+ console.log(' Events: ', webhook.events.join(', '));
206
+ console.log(' Status: ', webhook.status === 'active' ? '✅ Active' : '⏸️ Paused');
207
+ if (webhook.secret) {
208
+ console.log(' Secret: ', webhook.secret);
209
+ }
210
+ console.log(' Created: ', new Date(webhook.createdAt).toLocaleString());
211
+ if (webhook.lastDeliveryAttempt) {
212
+ const status = webhook.lastDeliveryStatus === 'success' ? '✅ Success' : '❌ Failed';
213
+ console.log(' Last: ', `${status} at ${new Date(webhook.lastDeliveryAttempt).toLocaleString()}`);
214
+ }
215
+ console.log();
216
+ } catch (err) {
217
+ error(`Failed to fetch webhook: ${(err as Error).message}`);
218
+ process.exit(1);
219
+ }
220
+ });
221
+
222
+ // Delete subcommand
223
+ cmd
224
+ .command('delete <id>')
225
+ .description('Delete a webhook')
226
+ .option('--json', 'Output as JSON')
227
+ .action(async (id: string, options: OutputOptions) => {
228
+ try {
229
+ const result = await withSpinner(
230
+ 'Deleting webhook...',
231
+ async () => {
232
+ const response = await fetch(`${API_URL}/api/v3/webhooks/${id}`, {
233
+ method: 'DELETE',
234
+ headers: {
235
+ 'Content-Type': 'application/json',
236
+ },
237
+ });
238
+
239
+ if (!response.ok) {
240
+ const err = await response.json() as { error?: string };
241
+ throw new Error(err.error || 'Failed to delete webhook');
242
+ }
243
+
244
+ return response.json() as Promise<{ success: boolean; message: string }>;
245
+ }
246
+ );
247
+
248
+ if (outputJSON(result, options)) {
249
+ return;
250
+ }
251
+
252
+ success('Webhook deleted successfully');
253
+ } catch (err) {
254
+ error(`Failed to delete webhook: ${(err as Error).message}`);
255
+ process.exit(1);
256
+ }
257
+ });
258
+
259
+ return cmd;
260
+ }
package/src/index.ts CHANGED
@@ -29,6 +29,11 @@ import { createHealthCommand } from './commands/health';
29
29
  import { createSearchCommand } from './commands/search';
30
30
  import { createExportCommand } from './commands/export';
31
31
  import { createTrustGraphCommand } from './commands/trust-graph';
32
+ import { createInitCommand } from './commands/init';
33
+ import { createLinkCommand } from './commands/link';
34
+ import { createWebhookCommand } from './commands/webhook';
35
+ import { createRefundCommand } from './commands/refund';
36
+ import { createAlertsCommand } from './commands/alerts';
32
37
  import chalk from 'chalk';
33
38
 
34
39
  // Load environment variables from .env file if present
@@ -83,6 +88,11 @@ program.addCommand(createHealthCommand());
83
88
  program.addCommand(createSearchCommand());
84
89
  program.addCommand(createExportCommand());
85
90
  program.addCommand(createTrustGraphCommand());
91
+ program.addCommand(createInitCommand());
92
+ program.addCommand(createLinkCommand());
93
+ program.addCommand(createWebhookCommand());
94
+ program.addCommand(createRefundCommand());
95
+ program.addCommand(createAlertsCommand());
86
96
  registerInvestCommand(program);
87
97
 
88
98
  // Handle errors
@@ -8,21 +8,21 @@ import type { Network, AgentInfo, Reputation, CreditStatus, EscrowInfo, Balance
8
8
  const CONTRACTS_MAINNET = {
9
9
  IDENTITY: '0xA174ee274F870631B3c330a85EBCad74120BE662' as Address,
10
10
  REPUTATION: '0x02bb4132a86134684976E2a52E43D59D89E64b29' as Address,
11
- CREDIT: '0xD9241Ce8a721Ef5fcCAc5A11983addC526eC80E1' as Address,
12
- ESCROW: '0x49EdEe04c78B7FeD5248A20706c7a6c540748806' as Address,
11
+ CREDIT: '0x4c22B52eacAB9eD2Ce018d032739a93eC68eD27a' as Address,
12
+ ESCROW: '0x703B528C1b07cd27992af9Ae11DD67bE685E489e' as Address,
13
13
  USDC: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' as Address,
14
- TRUST_GRAPH: '0x0000000000000000000000000000000000000000' as Address, // TODO: Deploy TrustGraph
14
+ TRUST_GRAPH: '0xbccd1d0a37ce981a13b3392d7881f94e28fa693b' as Address,
15
15
  };
16
16
 
17
17
  const CONTRACTS_SEPOLIA = {
18
18
  IDENTITY: '0x3dfA02Ed4F0e4F10E8031d7a4cB8Ea0bBbFbCB8c' as Address,
19
19
  // NOTE: Reputation address provided has 41 hex chars (invalid). Using placeholder.
20
- // Original (invalid): 0xb0033901e3b94f4F36dA0b3e396942C1e78205C7d
21
- REPUTATION: '0x0000000000000000000000000000000000000000' as Address, // TODO: Fix this address
20
+ // Was broken (41 hex chars) — fixed to correct address
21
+ REPUTATION: '0xb0033901e3b94f4F36dA0b3e59A1F4AD9f4f1697' as Address,
22
22
  CREDIT: '0xBA64e2b2F2a80D03A4B13b3396942C1e78205C7d' as Address,
23
23
  ESCROW: '0x78D1f50a1965dE34f6b5a3D3546C94FE1809Cd82' as Address,
24
24
  USDC: '0x036CbD53842c5426634e7929541eC2318f3dCF7e' as Address,
25
- TRUST_GRAPH: '0x0000000000000000000000000000000000000000' as Address, // TODO: Deploy TrustGraph
25
+ TRUST_GRAPH: '0xbccd1d0a37ce981a13b3392d7881f94e28fa693b' as Address,
26
26
  };
27
27
 
28
28
  // ABIs