arispay 0.1.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/.turbo/turbo-build.log +4 -0
- package/dist/chunk-4ON4ZXR3.js +953 -0
- package/dist/cli-b.js +277 -0
- package/dist/cli.js +426 -0
- package/dist/index.d.ts +216 -0
- package/dist/index.js +406 -0
- package/package.json +31 -0
- package/src/agents.ts +117 -0
- package/src/cli-b.ts +373 -0
- package/src/cli-shared.ts +650 -0
- package/src/cli.ts +439 -0
- package/src/client.ts +65 -0
- package/src/index.ts +98 -0
- package/src/payments.ts +22 -0
- package/src/transactions.ts +19 -0
- package/src/users.ts +67 -0
- package/src/webhooks.ts +81 -0
- package/tsconfig.json +8 -0
- package/tsup.config.ts +18 -0
package/src/agents.ts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
RegisterAgentRequest,
|
|
3
|
+
AgentResponse,
|
|
4
|
+
AgentListResponse,
|
|
5
|
+
RotateKeysResponse,
|
|
6
|
+
SetCircuitBreakerRequest,
|
|
7
|
+
CircuitBreakerResponse,
|
|
8
|
+
AgentTopupRequest,
|
|
9
|
+
AgentTopupResponse,
|
|
10
|
+
AgentSweepRequest,
|
|
11
|
+
AgentSweepResponse,
|
|
12
|
+
AgentEarningRequest,
|
|
13
|
+
AgentBalanceResponse,
|
|
14
|
+
LedgerHistoryResponse,
|
|
15
|
+
} from '@arispay/shared';
|
|
16
|
+
import type { HttpClient } from './client.js';
|
|
17
|
+
|
|
18
|
+
export interface ChildAgentSummary {
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
status: string;
|
|
22
|
+
permissions: string[];
|
|
23
|
+
delegatedBudget: number | null;
|
|
24
|
+
delegatedBudgetDay: number | null;
|
|
25
|
+
delegatedBudgetMo: number | null;
|
|
26
|
+
createdAt: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export class AgentService {
|
|
30
|
+
constructor(private client: HttpClient) {}
|
|
31
|
+
|
|
32
|
+
async register(params: RegisterAgentRequest): Promise<AgentResponse> {
|
|
33
|
+
return this.client.post<AgentResponse>('/v1/agents', params);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async get(agentId: string): Promise<AgentResponse> {
|
|
37
|
+
return this.client.get<AgentResponse>(`/v1/agents/${agentId}`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async list(params?: { name?: string; status?: string; limit?: number; offset?: number }): Promise<AgentListResponse> {
|
|
41
|
+
const query = new URLSearchParams();
|
|
42
|
+
if (params?.name) query.set('name', params.name);
|
|
43
|
+
if (params?.status) query.set('status', params.status);
|
|
44
|
+
if (params?.limit) query.set('limit', String(params.limit));
|
|
45
|
+
if (params?.offset) query.set('offset', String(params.offset));
|
|
46
|
+
const qs = query.toString();
|
|
47
|
+
return this.client.get<AgentListResponse>(`/v1/agents${qs ? `?${qs}` : ''}`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async listChildren(agentId: string): Promise<ChildAgentSummary[]> {
|
|
51
|
+
return this.client.get<ChildAgentSummary[]>(`/v1/agents/${agentId}/children`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async resume(agentId: string): Promise<{ status: string; resumedAt: string }> {
|
|
55
|
+
return this.client.post<{ status: string; resumedAt: string }>(`/v1/agents/${agentId}/resume`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async setCircuitBreaker(agentId: string, params: SetCircuitBreakerRequest): Promise<CircuitBreakerResponse> {
|
|
59
|
+
return this.client.put<CircuitBreakerResponse>(`/v1/agents/${agentId}/circuit-breaker`, params);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async getCircuitBreaker(agentId: string): Promise<CircuitBreakerResponse> {
|
|
63
|
+
return this.client.get<CircuitBreakerResponse>(`/v1/agents/${agentId}/circuit-breaker`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async rotateKeys(agentId: string): Promise<RotateKeysResponse> {
|
|
67
|
+
return this.client.post<RotateKeysResponse>(`/v1/agents/${agentId}/rotate-keys`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// ── Autonomous Agent Methods ──────────────────────────
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Get the current balance for an autonomous agent.
|
|
74
|
+
*/
|
|
75
|
+
async getBalance(agentId: string): Promise<AgentBalanceResponse> {
|
|
76
|
+
return this.client.get<AgentBalanceResponse>(`/v1/agents/${agentId}/balance`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Fund an autonomous agent's balance (topup).
|
|
81
|
+
*/
|
|
82
|
+
async topup(agentId: string, params: AgentTopupRequest): Promise<AgentTopupResponse> {
|
|
83
|
+
return this.client.post<AgentTopupResponse>(`/v1/agents/${agentId}/topup`, params);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Withdraw from an autonomous agent's balance (sweep).
|
|
88
|
+
* Omit `amount` to sweep everything above the sweep threshold.
|
|
89
|
+
*/
|
|
90
|
+
async sweep(agentId: string, params?: AgentSweepRequest): Promise<AgentSweepResponse> {
|
|
91
|
+
return this.client.post<AgentSweepResponse>(`/v1/agents/${agentId}/sweep`, params ?? {});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Get paginated ledger history for an autonomous agent.
|
|
96
|
+
*/
|
|
97
|
+
async getLedger(
|
|
98
|
+
agentId: string,
|
|
99
|
+
params?: { limit?: number; offset?: number; type?: string; from?: string; to?: string },
|
|
100
|
+
): Promise<LedgerHistoryResponse> {
|
|
101
|
+
const query = new URLSearchParams();
|
|
102
|
+
if (params?.limit) query.set('limit', String(params.limit));
|
|
103
|
+
if (params?.offset) query.set('offset', String(params.offset));
|
|
104
|
+
if (params?.type) query.set('type', params.type);
|
|
105
|
+
if (params?.from) query.set('from', params.from);
|
|
106
|
+
if (params?.to) query.set('to', params.to);
|
|
107
|
+
const qs = query.toString();
|
|
108
|
+
return this.client.get<LedgerHistoryResponse>(`/v1/agents/${agentId}/ledger${qs ? `?${qs}` : ''}`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Record an earning (inbound money) for an autonomous agent.
|
|
113
|
+
*/
|
|
114
|
+
async recordEarning(agentId: string, params: AgentEarningRequest): Promise<AgentTopupResponse> {
|
|
115
|
+
return this.client.post<AgentTopupResponse>(`/v1/agents/${agentId}/earn`, params);
|
|
116
|
+
}
|
|
117
|
+
}
|
package/src/cli-b.ts
ADDED
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PayAgent CLI — Device authorization flow
|
|
3
|
+
*
|
|
4
|
+
* npm install payagent
|
|
5
|
+
* payagent login → shows code, developer confirms on any browser
|
|
6
|
+
*
|
|
7
|
+
* No localhost server. Works in VMs, containers, SSH, WSL.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { randomBytes } from 'node:crypto';
|
|
11
|
+
import {
|
|
12
|
+
type Brand,
|
|
13
|
+
type Config,
|
|
14
|
+
createBrand,
|
|
15
|
+
configFile,
|
|
16
|
+
loadConfig,
|
|
17
|
+
saveConfig,
|
|
18
|
+
parseFlags,
|
|
19
|
+
error,
|
|
20
|
+
success,
|
|
21
|
+
dim,
|
|
22
|
+
bold,
|
|
23
|
+
cyan,
|
|
24
|
+
getVersion,
|
|
25
|
+
cmdAgents,
|
|
26
|
+
cmdUsers,
|
|
27
|
+
cmdPay,
|
|
28
|
+
cmdPaymentGet,
|
|
29
|
+
cmdTransactions,
|
|
30
|
+
cmdWebhooks,
|
|
31
|
+
cmdStatus,
|
|
32
|
+
} from './cli-shared.js';
|
|
33
|
+
|
|
34
|
+
const BRAND: Brand = createBrand('payagent', 'payagent login');
|
|
35
|
+
|
|
36
|
+
// ── Dashboard URLs ──────────────────────────────────────────────────
|
|
37
|
+
|
|
38
|
+
function getApiUrl(config: Config): string {
|
|
39
|
+
if (config.baseUrl) return config.baseUrl;
|
|
40
|
+
return config.environment === 'production'
|
|
41
|
+
? 'https://api.arispay.app'
|
|
42
|
+
: 'https://sandbox.api.arispay.app';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function getDeviceUrl(config: Config): string {
|
|
46
|
+
if (config.baseUrl) {
|
|
47
|
+
return config.baseUrl.replace('://api.', '://app.').replace('://sandbox.api.', '://app.');
|
|
48
|
+
}
|
|
49
|
+
return config.environment === 'production'
|
|
50
|
+
? 'https://app.arispay.app'
|
|
51
|
+
: 'https://app.sandbox.arispay.app';
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// ── Device flow helpers ─────────────────────────────────────────────
|
|
55
|
+
|
|
56
|
+
function generateUserCode(): string {
|
|
57
|
+
// 8-char alphanumeric, formatted as XXXX-XXXX for readability
|
|
58
|
+
const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'; // no 0/O/1/I ambiguity
|
|
59
|
+
let code = '';
|
|
60
|
+
const bytes = randomBytes(8);
|
|
61
|
+
for (let i = 0; i < 8; i++) {
|
|
62
|
+
code += chars[bytes[i] % chars.length];
|
|
63
|
+
}
|
|
64
|
+
return `${code.slice(0, 4)}-${code.slice(4)}`;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
interface DeviceCodeResponse {
|
|
68
|
+
deviceCode: string;
|
|
69
|
+
userCode: string;
|
|
70
|
+
verificationUrl: string;
|
|
71
|
+
expiresIn: number;
|
|
72
|
+
interval: number;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
interface TokenResponse {
|
|
76
|
+
accessToken: string;
|
|
77
|
+
refreshToken?: string;
|
|
78
|
+
expiresAt?: number;
|
|
79
|
+
email?: string;
|
|
80
|
+
environment?: string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function requestDeviceCode(apiUrl: string): Promise<DeviceCodeResponse> {
|
|
84
|
+
const res = await fetch(`${apiUrl}/v1/auth/device/code`, {
|
|
85
|
+
method: 'POST',
|
|
86
|
+
headers: { 'Content-Type': 'application/json' },
|
|
87
|
+
body: JSON.stringify({ clientId: 'payagent-cli' }),
|
|
88
|
+
signal: AbortSignal.timeout(15_000),
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
if (!res.ok) {
|
|
92
|
+
const body = await res.json().catch(() => ({}));
|
|
93
|
+
throw new Error((body as any).error?.message || `Device code request failed (HTTP ${res.status})`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return res.json() as Promise<DeviceCodeResponse>;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async function pollForToken(
|
|
100
|
+
apiUrl: string,
|
|
101
|
+
deviceCode: string,
|
|
102
|
+
intervalSec: number,
|
|
103
|
+
expiresIn: number,
|
|
104
|
+
): Promise<TokenResponse> {
|
|
105
|
+
const deadline = Date.now() + expiresIn * 1000;
|
|
106
|
+
|
|
107
|
+
while (Date.now() < deadline) {
|
|
108
|
+
await sleep(intervalSec * 1000);
|
|
109
|
+
|
|
110
|
+
const res = await fetch(`${apiUrl}/v1/auth/device/token`, {
|
|
111
|
+
method: 'POST',
|
|
112
|
+
headers: { 'Content-Type': 'application/json' },
|
|
113
|
+
body: JSON.stringify({ deviceCode, clientId: 'payagent-cli' }),
|
|
114
|
+
signal: AbortSignal.timeout(15_000),
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
const body = await res.json() as any;
|
|
118
|
+
|
|
119
|
+
if (res.ok && body.accessToken) {
|
|
120
|
+
return body as TokenResponse;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Standard device flow responses
|
|
124
|
+
const errorCode = body.error?.code || body.error;
|
|
125
|
+
if (errorCode === 'authorization_pending') {
|
|
126
|
+
continue; // keep polling
|
|
127
|
+
} else if (errorCode === 'slow_down') {
|
|
128
|
+
intervalSec = Math.min(intervalSec + 1, 10); // back off
|
|
129
|
+
continue;
|
|
130
|
+
} else if (errorCode === 'expired_token') {
|
|
131
|
+
throw new Error('Login expired. Run `payagent login` to try again.');
|
|
132
|
+
} else if (errorCode === 'access_denied') {
|
|
133
|
+
throw new Error('Login was denied.');
|
|
134
|
+
} else {
|
|
135
|
+
throw new Error(body.error?.message || `Token request failed (HTTP ${res.status})`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
throw new Error('Login timed out. Run `payagent login` to try again.');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function sleep(ms: number): Promise<void> {
|
|
143
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// ── Login (device flow) ─────────────────────────────────────────────
|
|
147
|
+
|
|
148
|
+
async function cmdLogin(args: string[]): Promise<void> {
|
|
149
|
+
const { flags } = parseFlags(args);
|
|
150
|
+
const config = loadConfig(BRAND);
|
|
151
|
+
|
|
152
|
+
// CI escape hatch: payagent login --api-key <key>
|
|
153
|
+
if (flags['api-key']) {
|
|
154
|
+
saveConfig(BRAND, {
|
|
155
|
+
...config,
|
|
156
|
+
apiKey: flags['api-key'],
|
|
157
|
+
environment: (flags['env'] as Config['environment']) || config.environment,
|
|
158
|
+
});
|
|
159
|
+
success('API key saved');
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const apiUrl = getApiUrl(config);
|
|
164
|
+
const dashboardUrl = getDeviceUrl(config);
|
|
165
|
+
|
|
166
|
+
console.log(`\n${bold('PayAgent Login')}\n`);
|
|
167
|
+
|
|
168
|
+
// Step 1: Request device code from API
|
|
169
|
+
let device: DeviceCodeResponse;
|
|
170
|
+
try {
|
|
171
|
+
device = await requestDeviceCode(apiUrl);
|
|
172
|
+
} catch (e: any) {
|
|
173
|
+
error(e.message || 'Could not initiate login');
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const verificationUrl = device!.verificationUrl || `${dashboardUrl}/device`;
|
|
177
|
+
|
|
178
|
+
// Step 2: Show code to developer
|
|
179
|
+
console.log(` Open this URL on any device:\n`);
|
|
180
|
+
console.log(` ${cyan(verificationUrl)}\n`);
|
|
181
|
+
console.log(` Then enter this code:\n`);
|
|
182
|
+
console.log(` ${bold(device!.userCode)}\n`);
|
|
183
|
+
|
|
184
|
+
// Step 3: Poll for token
|
|
185
|
+
const spinner = startSpinner(' Waiting for confirmation');
|
|
186
|
+
|
|
187
|
+
try {
|
|
188
|
+
const token = await pollForToken(
|
|
189
|
+
apiUrl,
|
|
190
|
+
device!.deviceCode,
|
|
191
|
+
device!.interval || 5,
|
|
192
|
+
device!.expiresIn || 300,
|
|
193
|
+
);
|
|
194
|
+
spinner.stop();
|
|
195
|
+
|
|
196
|
+
// Save credentials
|
|
197
|
+
saveConfig(BRAND, {
|
|
198
|
+
...config,
|
|
199
|
+
accessToken: token.accessToken,
|
|
200
|
+
refreshToken: token.refreshToken,
|
|
201
|
+
expiresAt: token.expiresAt,
|
|
202
|
+
email: token.email,
|
|
203
|
+
environment: (token.environment as Config['environment']) || config.environment,
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
console.log();
|
|
207
|
+
success(`Logged in as ${bold(token.email || 'developer')}`);
|
|
208
|
+
if (token.environment) {
|
|
209
|
+
console.log(` ${bold('Environment:')} ${token.environment}`);
|
|
210
|
+
}
|
|
211
|
+
console.log(` ${bold('Config:')} ${dim(configFile(BRAND))}`);
|
|
212
|
+
console.log();
|
|
213
|
+
} catch (e: any) {
|
|
214
|
+
spinner.stop();
|
|
215
|
+
console.log();
|
|
216
|
+
error(e.message || 'Authentication failed');
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// ── Logout ──────────────────────────────────────────────────────────
|
|
221
|
+
|
|
222
|
+
async function cmdLogout(): Promise<void> {
|
|
223
|
+
const config = loadConfig(BRAND);
|
|
224
|
+
|
|
225
|
+
if (!config.accessToken && !config.apiKey && !config.email) {
|
|
226
|
+
console.log(dim('\n Not logged in.\n'));
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Clear auth fields, keep environment/baseUrl preferences
|
|
231
|
+
saveConfig(BRAND, {
|
|
232
|
+
environment: config.environment,
|
|
233
|
+
baseUrl: config.baseUrl,
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
success('Logged out');
|
|
237
|
+
console.log(` ${dim('Cleared credentials from')} ${configFile(BRAND)}\n`);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// ── Spinner ─────────────────────────────────────────────────────────
|
|
241
|
+
|
|
242
|
+
function startSpinner(message: string): { stop: () => void } {
|
|
243
|
+
const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
244
|
+
let i = 0;
|
|
245
|
+
const interval = setInterval(() => {
|
|
246
|
+
process.stdout.write(`\r${frames[i++ % frames.length]} ${message}`);
|
|
247
|
+
}, 80);
|
|
248
|
+
|
|
249
|
+
return {
|
|
250
|
+
stop() {
|
|
251
|
+
clearInterval(interval);
|
|
252
|
+
process.stdout.write('\r' + ' '.repeat(message.length + 4) + '\r');
|
|
253
|
+
},
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// ── Whoami ──────────────────────────────────────────────────────────
|
|
258
|
+
|
|
259
|
+
async function cmdWhoami(): Promise<void> {
|
|
260
|
+
const config = loadConfig(BRAND);
|
|
261
|
+
if (config.email) {
|
|
262
|
+
console.log(config.email);
|
|
263
|
+
} else if (config.apiKey || config.accessToken) {
|
|
264
|
+
const key = (config.apiKey || config.accessToken)!;
|
|
265
|
+
console.log(`api-key: ${key.slice(0, 12)}…${key.slice(-4)}`);
|
|
266
|
+
} else {
|
|
267
|
+
error('Not logged in. Run: payagent login');
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// ── Main ────────────────────────────────────────────────────────────
|
|
272
|
+
|
|
273
|
+
const HELP = `
|
|
274
|
+
${bold('payagent')} — Agentic payment infrastructure CLI
|
|
275
|
+
|
|
276
|
+
${bold('Usage:')}
|
|
277
|
+
payagent <command> [options]
|
|
278
|
+
|
|
279
|
+
${bold('Auth:')}
|
|
280
|
+
${cyan('login')} Authenticate via device code
|
|
281
|
+
${cyan('logout')} Clear stored credentials
|
|
282
|
+
${cyan('whoami')} Show current identity
|
|
283
|
+
|
|
284
|
+
${bold('Commands:')}
|
|
285
|
+
${cyan('status')} Show config & connection status
|
|
286
|
+
${cyan('agents')} Manage AI payment agents
|
|
287
|
+
${cyan('users')} Manage end users & payment methods
|
|
288
|
+
${cyan('pay')} Create a payment
|
|
289
|
+
${cyan('payment <id>')} Get payment details
|
|
290
|
+
${cyan('transactions')} List transactions
|
|
291
|
+
${cyan('webhooks')} Manage webhook endpoints
|
|
292
|
+
|
|
293
|
+
${bold('Examples:')}
|
|
294
|
+
payagent login
|
|
295
|
+
payagent agents create --name "BookingBot" --mode autonomous
|
|
296
|
+
payagent agents list
|
|
297
|
+
payagent pay --agent <id> --amount 2000 --memo "Dinner for 2"
|
|
298
|
+
payagent transactions --agent <id> --from 2025-01-01
|
|
299
|
+
|
|
300
|
+
${bold('Environment:')}
|
|
301
|
+
PAYAGENT_API_KEY Override auth (CI/scripting)
|
|
302
|
+
PAYAGENT_ENV Override environment (sandbox|production)
|
|
303
|
+
PAYAGENT_BASE_URL Override API base URL
|
|
304
|
+
|
|
305
|
+
${bold('Config:')} ~/.payagent/config.json
|
|
306
|
+
`;
|
|
307
|
+
|
|
308
|
+
async function main(): Promise<void> {
|
|
309
|
+
const args = process.argv.slice(2);
|
|
310
|
+
const command = args[0];
|
|
311
|
+
const rest = args.slice(1);
|
|
312
|
+
|
|
313
|
+
if (!command || command === 'help' || command === '--help' || command === '-h') {
|
|
314
|
+
console.log(HELP);
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
if (command === '--version' || command === '-v') {
|
|
319
|
+
console.log(getVersion());
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
try {
|
|
324
|
+
switch (command) {
|
|
325
|
+
case 'login':
|
|
326
|
+
await cmdLogin(rest);
|
|
327
|
+
break;
|
|
328
|
+
case 'logout':
|
|
329
|
+
await cmdLogout();
|
|
330
|
+
break;
|
|
331
|
+
case 'whoami':
|
|
332
|
+
await cmdWhoami();
|
|
333
|
+
break;
|
|
334
|
+
case 'status':
|
|
335
|
+
await cmdStatus(BRAND);
|
|
336
|
+
break;
|
|
337
|
+
case 'agents':
|
|
338
|
+
case 'agent':
|
|
339
|
+
await cmdAgents(rest, BRAND);
|
|
340
|
+
break;
|
|
341
|
+
case 'users':
|
|
342
|
+
case 'user':
|
|
343
|
+
await cmdUsers(rest, BRAND);
|
|
344
|
+
break;
|
|
345
|
+
case 'pay':
|
|
346
|
+
await cmdPay(rest, BRAND);
|
|
347
|
+
break;
|
|
348
|
+
case 'payment':
|
|
349
|
+
await cmdPaymentGet(rest, BRAND);
|
|
350
|
+
break;
|
|
351
|
+
case 'transactions':
|
|
352
|
+
case 'txs':
|
|
353
|
+
await cmdTransactions(rest, BRAND);
|
|
354
|
+
break;
|
|
355
|
+
case 'webhooks':
|
|
356
|
+
case 'webhook':
|
|
357
|
+
await cmdWebhooks(rest, BRAND);
|
|
358
|
+
break;
|
|
359
|
+
default:
|
|
360
|
+
console.error(`Unknown command: ${command}`);
|
|
361
|
+
console.log(HELP);
|
|
362
|
+
process.exit(1);
|
|
363
|
+
}
|
|
364
|
+
} catch (e: any) {
|
|
365
|
+
if (e.code && e.message && e.statusCode) {
|
|
366
|
+
error(`[${e.code}] ${e.message} (HTTP ${e.statusCode})`);
|
|
367
|
+
} else {
|
|
368
|
+
error(e.message || String(e));
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
main();
|