@alchemy/cli 0.6.2 → 0.7.0-alpha.5
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 +49 -61
- package/dist/auth-I5WFLU46.js +16 -0
- package/dist/{auth-S4DTOWW3.js → auth-JGON2JU6.js} +10 -8
- package/dist/{chunk-TK3HZ5UT.js → chunk-5MXODL63.js} +3 -3
- package/dist/{chunk-NBDWF4ZQ.js → chunk-A6L3WCJN.js} +32 -22
- package/dist/{chunk-BAAQ7ELR.js → chunk-B3R6PRAL.js} +59 -4
- package/dist/{chunk-FFMNT74F.js → chunk-HSKKIATB.js} +125 -76
- package/dist/{chunk-KDMIWPZH.js → chunk-HYCRHNPX.js} +1 -1
- package/dist/chunk-MUT4TFQ5.js +64 -0
- package/dist/{chunk-UMKDYHMO.js → chunk-NT3G6BKD.js} +54 -99
- package/dist/{chunk-ATX65U7J.js → chunk-PKAN5FKD.js} +570 -41
- package/dist/{chunk-56ZVYB4G.js → chunk-QEDAULQ2.js} +263 -222
- package/dist/errors-3CNFGAXT.js +54 -0
- package/dist/index.js +6668 -2166
- package/dist/{interactive-UGD7GYJM.js → interactive-VXPD6N7Z.js} +56 -61
- package/dist/{onboarding-IP4R44EQ.js → onboarding-CEHXSNYD.js} +14 -11
- package/dist/resolve-X7HLVLGA.js +50 -0
- package/package.json +12 -3
- package/scripts/postinstall.cjs +69 -1
- package/dist/auth-QB3BA7AN.js +0 -17
- package/dist/chunk-JQRGILIS.js +0 -53
- package/dist/chunk-T5Z2GJUX.js +0 -331
- package/dist/credential-storage-T6FFW7DG.js +0 -14
- package/dist/resolve-HXKHDOJZ.js +0 -31
|
@@ -12,203 +12,48 @@ var esc = (code) => (s) => noColor ? s : `\x1B[${code}m${s}\x1B[0m`;
|
|
|
12
12
|
var rgb = (r, g, b) => (s) => noColor ? s : `\x1B[38;2;${r};${g};${b}m${s}\x1B[39m`;
|
|
13
13
|
var bgRgb = (r, g, b) => (s) => noColor ? s : `\x1B[48;2;${r};${g};${b}m${s}\x1B[49m`;
|
|
14
14
|
|
|
15
|
-
// src/lib/
|
|
16
|
-
var
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
PAYMENT_REQUIRED: "PAYMENT_REQUIRED",
|
|
30
|
-
SETUP_REQUIRED: "SETUP_REQUIRED",
|
|
31
|
-
INTERNAL_ERROR: "INTERNAL_ERROR"
|
|
32
|
-
};
|
|
33
|
-
var RETRYABLE_CODES = /* @__PURE__ */ new Set([
|
|
34
|
-
ErrorCode.RATE_LIMITED,
|
|
35
|
-
ErrorCode.NETWORK_ERROR
|
|
36
|
-
]);
|
|
37
|
-
var EXIT_CODES = {
|
|
38
|
-
AUTH_REQUIRED: 3,
|
|
39
|
-
INVALID_API_KEY: 3,
|
|
40
|
-
NETWORK_NOT_ENABLED: 3,
|
|
41
|
-
INVALID_ACCESS_KEY: 3,
|
|
42
|
-
ACCESS_KEY_REQUIRED: 3,
|
|
43
|
-
APP_REQUIRED: 3,
|
|
44
|
-
INVALID_ARGS: 2,
|
|
45
|
-
NOT_FOUND: 4,
|
|
46
|
-
RATE_LIMITED: 5,
|
|
47
|
-
NETWORK_ERROR: 6,
|
|
48
|
-
RPC_ERROR: 7,
|
|
49
|
-
ADMIN_API_ERROR: 8,
|
|
50
|
-
PAYMENT_REQUIRED: 9,
|
|
51
|
-
SETUP_REQUIRED: 3,
|
|
52
|
-
INTERNAL_ERROR: 1
|
|
53
|
-
};
|
|
54
|
-
var CLIError = class extends Error {
|
|
55
|
-
code;
|
|
56
|
-
hint;
|
|
57
|
-
details;
|
|
58
|
-
data;
|
|
59
|
-
constructor(code, message, hint, details, data) {
|
|
60
|
-
super(message);
|
|
61
|
-
this.name = "CLIError";
|
|
62
|
-
this.code = code;
|
|
63
|
-
this.hint = hint;
|
|
64
|
-
this.details = details;
|
|
65
|
-
this.data = data;
|
|
66
|
-
}
|
|
67
|
-
toJSON() {
|
|
68
|
-
return {
|
|
69
|
-
error: {
|
|
70
|
-
code: this.code,
|
|
71
|
-
message: this.message,
|
|
72
|
-
...this.hint && { hint: this.hint },
|
|
73
|
-
...this.details && { details: this.details },
|
|
74
|
-
...this.data !== void 0 && { data: this.data },
|
|
75
|
-
retryable: RETRYABLE_CODES.has(this.code)
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
format() {
|
|
80
|
-
let out = `${this.code}: ${this.message}`;
|
|
81
|
-
if (this.hint) out += `
|
|
82
|
-
Hint: ${this.hint}`;
|
|
83
|
-
return out;
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
function errAuthRequired() {
|
|
87
|
-
return new CLIError(
|
|
88
|
-
ErrorCode.AUTH_REQUIRED,
|
|
89
|
-
"Not authenticated. Run 'alchemy auth' to log in, or set ALCHEMY_API_KEY.",
|
|
90
|
-
"alchemy auth"
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
function errAccessKeyRequired() {
|
|
94
|
-
return new CLIError(
|
|
95
|
-
ErrorCode.ACCESS_KEY_REQUIRED,
|
|
96
|
-
"Access key required. Set ALCHEMY_ACCESS_KEY or run 'alchemy config set access-key <key>'.",
|
|
97
|
-
"Get an access key: https://www.alchemy.com/docs/reference/admin-api/overview"
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
function errInvalidAPIKey(details) {
|
|
101
|
-
return new CLIError(
|
|
102
|
-
ErrorCode.INVALID_API_KEY,
|
|
103
|
-
"Invalid API key. Check your key and try again.",
|
|
104
|
-
"alchemy config set api-key <your-key>",
|
|
105
|
-
details
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
function errNetworkNotEnabled(network, details) {
|
|
109
|
-
const networkLabel = network.toLowerCase().replace(/_/g, "-");
|
|
110
|
-
return new CLIError(
|
|
111
|
-
ErrorCode.NETWORK_NOT_ENABLED,
|
|
112
|
-
`API key is valid, but ${networkLabel} is not enabled for this app.`,
|
|
113
|
-
void 0,
|
|
114
|
-
details
|
|
115
|
-
);
|
|
116
|
-
}
|
|
117
|
-
function errNetwork(detail) {
|
|
118
|
-
return new CLIError(
|
|
119
|
-
ErrorCode.NETWORK_ERROR,
|
|
120
|
-
`Network error: ${detail}`,
|
|
121
|
-
"Check your internet connection and try again."
|
|
122
|
-
);
|
|
123
|
-
}
|
|
124
|
-
var RPC_ERROR_HINTS = {
|
|
125
|
-
[-32700]: "Parse error. The request JSON is malformed.",
|
|
126
|
-
[-32600]: "Invalid request. Check the JSON-RPC request format.",
|
|
127
|
-
[-32601]: "Method not supported. Check the method name and ensure your plan supports it.",
|
|
128
|
-
[-32602]: "Invalid parameters. Check argument types and format.",
|
|
129
|
-
[-32603]: "Internal JSON-RPC error."
|
|
130
|
-
};
|
|
131
|
-
function errRPC(code, message) {
|
|
132
|
-
const hint = RPC_ERROR_HINTS[code];
|
|
133
|
-
return new CLIError(ErrorCode.RPC_ERROR, `RPC error ${code}: ${message}`, hint);
|
|
134
|
-
}
|
|
135
|
-
function errInvalidArgs(detail) {
|
|
136
|
-
return new CLIError(ErrorCode.INVALID_ARGS, detail);
|
|
137
|
-
}
|
|
138
|
-
function errNotFound(resource) {
|
|
139
|
-
return new CLIError(ErrorCode.NOT_FOUND, `Not found: ${resource}`);
|
|
140
|
-
}
|
|
141
|
-
function errRateLimited() {
|
|
142
|
-
return new CLIError(
|
|
143
|
-
ErrorCode.RATE_LIMITED,
|
|
144
|
-
"Rate limited. Please wait and try again.",
|
|
145
|
-
"Consider upgrading your Alchemy plan for higher rate limits."
|
|
146
|
-
);
|
|
147
|
-
}
|
|
148
|
-
function errInvalidAccessKey() {
|
|
149
|
-
return new CLIError(
|
|
150
|
-
ErrorCode.INVALID_ACCESS_KEY,
|
|
151
|
-
"Invalid access key. Check your key and try again.",
|
|
152
|
-
"Get an access key: https://www.alchemy.com/docs/reference/admin-api/overview"
|
|
153
|
-
);
|
|
154
|
-
}
|
|
155
|
-
function errAccessDenied(detail) {
|
|
156
|
-
const message = detail ? `Access denied: ${detail}` : "Access denied. Your access key may not have permission for this operation.";
|
|
157
|
-
return new CLIError(
|
|
158
|
-
ErrorCode.INVALID_ACCESS_KEY,
|
|
159
|
-
message,
|
|
160
|
-
"Check your account tier and feature access at https://dashboard.alchemy.com/"
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
|
-
function errAppRequired() {
|
|
164
|
-
return new CLIError(
|
|
165
|
-
ErrorCode.APP_REQUIRED,
|
|
166
|
-
"No app selected. Set an app to resolve the API key automatically.",
|
|
167
|
-
"alchemy config set app <app-id>"
|
|
168
|
-
);
|
|
15
|
+
// src/lib/output.ts
|
|
16
|
+
var forceJSON = false;
|
|
17
|
+
var quiet = false;
|
|
18
|
+
var verbose = false;
|
|
19
|
+
var debugMode = false;
|
|
20
|
+
var timeout;
|
|
21
|
+
var reveal = false;
|
|
22
|
+
function setFlags(opts) {
|
|
23
|
+
forceJSON = opts.json ?? false;
|
|
24
|
+
quiet = opts.quiet ?? false;
|
|
25
|
+
verbose = opts.verbose ?? false;
|
|
26
|
+
debugMode = opts.debug ?? false;
|
|
27
|
+
reveal = opts.reveal ?? false;
|
|
28
|
+
timeout = opts.timeout;
|
|
169
29
|
}
|
|
170
|
-
function
|
|
171
|
-
return
|
|
172
|
-
ErrorCode.AUTH_REQUIRED,
|
|
173
|
-
"Wallet key required for x402. Set ALCHEMY_WALLET_KEY, run 'alchemy wallet generate', or use --wallet-key-file.",
|
|
174
|
-
"alchemy wallet generate"
|
|
175
|
-
);
|
|
30
|
+
function isRevealMode() {
|
|
31
|
+
return reveal;
|
|
176
32
|
}
|
|
177
|
-
function
|
|
178
|
-
return
|
|
179
|
-
|
|
180
|
-
`Admin API error (HTTP ${status}): ${message}`
|
|
181
|
-
);
|
|
33
|
+
function isJSONMode() {
|
|
34
|
+
if (forceJSON) return true;
|
|
35
|
+
return !process.stdout.isTTY;
|
|
182
36
|
}
|
|
183
|
-
function
|
|
184
|
-
|
|
185
|
-
ErrorCode.SETUP_REQUIRED,
|
|
186
|
-
"Setup required before running in non-interactive mode.",
|
|
187
|
-
"Run 'alchemy' in a TTY for guided onboarding, or run 'alchemy setup status --json' for machine-readable remediation steps.",
|
|
188
|
-
void 0,
|
|
189
|
-
data
|
|
190
|
-
);
|
|
37
|
+
function printJSON(value) {
|
|
38
|
+
console.log(JSON.stringify(value, null, 2));
|
|
191
39
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
40
|
+
function printHuman(humanText, jsonValue) {
|
|
41
|
+
if (isJSONMode()) {
|
|
42
|
+
printJSON(jsonValue);
|
|
43
|
+
} else {
|
|
44
|
+
process.stdout.write(humanText);
|
|
45
|
+
}
|
|
195
46
|
}
|
|
196
|
-
function
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
err instanceof Error ? err.message : String(err)
|
|
200
|
-
);
|
|
201
|
-
printError(cliErr);
|
|
202
|
-
if (replMode) {
|
|
203
|
-
throw cliErr;
|
|
47
|
+
function debug(message, ...args) {
|
|
48
|
+
if (debugMode) {
|
|
49
|
+
console.error(`[debug] ${message}`, ...args);
|
|
204
50
|
}
|
|
205
|
-
process.exit(EXIT_CODES[cliErr.code]);
|
|
206
51
|
}
|
|
207
52
|
|
|
208
53
|
// src/lib/client-utils.ts
|
|
209
54
|
var DEFAULT_BASE_DOMAIN = "alchemy.com";
|
|
210
55
|
function getBaseDomain() {
|
|
211
|
-
if (process.env.
|
|
56
|
+
if (process.env.ALCHEMY_BASE_DOMAIN) {
|
|
212
57
|
return process.env.ALCHEMY_BASE_DOMAIN;
|
|
213
58
|
}
|
|
214
59
|
return DEFAULT_BASE_DOMAIN;
|
|
@@ -216,7 +61,7 @@ function getBaseDomain() {
|
|
|
216
61
|
function isLocalhost(hostname) {
|
|
217
62
|
return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1";
|
|
218
63
|
}
|
|
219
|
-
function parseBaseURLOverride(envVarName) {
|
|
64
|
+
function parseBaseURLOverride(envVarName, options = {}) {
|
|
220
65
|
const raw = process.env[envVarName];
|
|
221
66
|
if (!raw) return null;
|
|
222
67
|
let parsed;
|
|
@@ -225,9 +70,12 @@ function parseBaseURLOverride(envVarName) {
|
|
|
225
70
|
} catch {
|
|
226
71
|
throw errInvalidArgs(`Invalid ${envVarName} value.`);
|
|
227
72
|
}
|
|
228
|
-
|
|
73
|
+
const allowedHostnames = options.allowedHostnames ?? [];
|
|
74
|
+
const isAllowedHost = allowedHostnames.includes(parsed.hostname);
|
|
75
|
+
if (!isLocalhost(parsed.hostname) && !isAllowedHost) {
|
|
76
|
+
const targetDescription = allowedHostnames.length > 0 ? `localhost or one of: ${allowedHostnames.join(", ")}` : "localhost or 127.0.0.1";
|
|
229
77
|
throw errInvalidArgs(
|
|
230
|
-
`${envVarName} must target
|
|
78
|
+
`${envVarName} must target ${targetDescription}.`
|
|
231
79
|
);
|
|
232
80
|
}
|
|
233
81
|
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
|
|
@@ -270,7 +118,7 @@ async function fetchWithTimeout(url, init) {
|
|
|
270
118
|
const networkSlug = hostname.replace(new RegExp(`\\.g\\.${escapeRegExp(getBaseDomain())}$`), "");
|
|
271
119
|
if (networkSlug !== hostname) {
|
|
272
120
|
throw errInvalidArgs(
|
|
273
|
-
`Unknown network '${networkSlug}'. Run 'alchemy network list' to see available networks.`
|
|
121
|
+
`Unknown network '${networkSlug}'. Run 'alchemy evm network list' to see available networks.`
|
|
274
122
|
);
|
|
275
123
|
}
|
|
276
124
|
} catch (innerErr) {
|
|
@@ -352,10 +200,15 @@ function toSafeErrorJSON(err) {
|
|
|
352
200
|
}
|
|
353
201
|
function wrapWithPrefix(text, prefix, width) {
|
|
354
202
|
const safeWidth = Math.max(20, width - prefix.length);
|
|
203
|
+
const continuation = " ".repeat(prefix.length);
|
|
355
204
|
const words = text.trim().split(/\s+/);
|
|
356
205
|
if (words.length === 0 || words.length === 1 && words[0] === "") return [prefix];
|
|
357
206
|
const lines = [];
|
|
358
207
|
let current = "";
|
|
208
|
+
const flush = () => {
|
|
209
|
+
const linePrefix = lines.length === 0 ? prefix : continuation;
|
|
210
|
+
lines.push(`${linePrefix}${current}`);
|
|
211
|
+
};
|
|
359
212
|
for (const word of words) {
|
|
360
213
|
if (current.length === 0) {
|
|
361
214
|
current = word;
|
|
@@ -364,12 +217,12 @@ function wrapWithPrefix(text, prefix, width) {
|
|
|
364
217
|
if (current.length + 1 + word.length <= safeWidth) {
|
|
365
218
|
current += ` ${word}`;
|
|
366
219
|
} else {
|
|
367
|
-
|
|
220
|
+
flush();
|
|
368
221
|
current = word;
|
|
369
222
|
}
|
|
370
223
|
}
|
|
371
224
|
if (current.length > 0) {
|
|
372
|
-
|
|
225
|
+
flush();
|
|
373
226
|
}
|
|
374
227
|
return lines;
|
|
375
228
|
}
|
|
@@ -454,42 +307,226 @@ ${styled.join("\n")}
|
|
|
454
307
|
`;
|
|
455
308
|
}
|
|
456
309
|
|
|
457
|
-
// src/lib/
|
|
458
|
-
var
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
310
|
+
// src/lib/errors.ts
|
|
311
|
+
var ErrorCode = {
|
|
312
|
+
AUTH_REQUIRED: "AUTH_REQUIRED",
|
|
313
|
+
INVALID_API_KEY: "INVALID_API_KEY",
|
|
314
|
+
NETWORK_NOT_ENABLED: "NETWORK_NOT_ENABLED",
|
|
315
|
+
INVALID_ACCESS_KEY: "INVALID_ACCESS_KEY",
|
|
316
|
+
ACCESS_KEY_REQUIRED: "ACCESS_KEY_REQUIRED",
|
|
317
|
+
APP_REQUIRED: "APP_REQUIRED",
|
|
318
|
+
ADMIN_API_ERROR: "ADMIN_API_ERROR",
|
|
319
|
+
NETWORK_ERROR: "NETWORK_ERROR",
|
|
320
|
+
RPC_ERROR: "RPC_ERROR",
|
|
321
|
+
INVALID_ARGS: "INVALID_ARGS",
|
|
322
|
+
NOT_FOUND: "NOT_FOUND",
|
|
323
|
+
RATE_LIMITED: "RATE_LIMITED",
|
|
324
|
+
PAYMENT_REQUIRED: "PAYMENT_REQUIRED",
|
|
325
|
+
SETUP_REQUIRED: "SETUP_REQUIRED",
|
|
326
|
+
INTERNAL_ERROR: "INTERNAL_ERROR"
|
|
327
|
+
};
|
|
328
|
+
var RETRYABLE_CODES = /* @__PURE__ */ new Set([
|
|
329
|
+
ErrorCode.RATE_LIMITED,
|
|
330
|
+
ErrorCode.NETWORK_ERROR
|
|
331
|
+
]);
|
|
332
|
+
var EXIT_CODES = {
|
|
333
|
+
AUTH_REQUIRED: 3,
|
|
334
|
+
INVALID_API_KEY: 3,
|
|
335
|
+
NETWORK_NOT_ENABLED: 3,
|
|
336
|
+
INVALID_ACCESS_KEY: 3,
|
|
337
|
+
ACCESS_KEY_REQUIRED: 3,
|
|
338
|
+
APP_REQUIRED: 3,
|
|
339
|
+
INVALID_ARGS: 2,
|
|
340
|
+
NOT_FOUND: 4,
|
|
341
|
+
RATE_LIMITED: 5,
|
|
342
|
+
NETWORK_ERROR: 6,
|
|
343
|
+
RPC_ERROR: 7,
|
|
344
|
+
ADMIN_API_ERROR: 8,
|
|
345
|
+
PAYMENT_REQUIRED: 9,
|
|
346
|
+
SETUP_REQUIRED: 3,
|
|
347
|
+
INTERNAL_ERROR: 1
|
|
348
|
+
};
|
|
349
|
+
var CLIError = class extends Error {
|
|
350
|
+
code;
|
|
351
|
+
hint;
|
|
352
|
+
details;
|
|
353
|
+
data;
|
|
354
|
+
constructor(code, message, hint, details, data) {
|
|
355
|
+
super(message);
|
|
356
|
+
this.name = "CLIError";
|
|
357
|
+
this.code = code;
|
|
358
|
+
this.hint = hint;
|
|
359
|
+
this.details = details;
|
|
360
|
+
this.data = data;
|
|
361
|
+
}
|
|
362
|
+
toJSON() {
|
|
363
|
+
return {
|
|
364
|
+
error: {
|
|
365
|
+
code: this.code,
|
|
366
|
+
message: this.message,
|
|
367
|
+
...this.hint && { hint: this.hint },
|
|
368
|
+
...this.details && { details: this.details },
|
|
369
|
+
...this.data !== void 0 && { data: this.data },
|
|
370
|
+
retryable: RETRYABLE_CODES.has(this.code)
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
format() {
|
|
375
|
+
let out = `${this.code}: ${this.message}`;
|
|
376
|
+
if (this.hint) out += `
|
|
377
|
+
Hint: ${this.hint}`;
|
|
378
|
+
return out;
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
function errAuthRequired() {
|
|
382
|
+
return new CLIError(
|
|
383
|
+
ErrorCode.AUTH_REQUIRED,
|
|
384
|
+
"Not authenticated. Run 'alchemy auth' to log in, or set ALCHEMY_API_KEY.",
|
|
385
|
+
"alchemy auth"
|
|
386
|
+
);
|
|
471
387
|
}
|
|
472
|
-
function
|
|
473
|
-
return
|
|
388
|
+
function errAccessKeyRequired() {
|
|
389
|
+
return new CLIError(
|
|
390
|
+
ErrorCode.ACCESS_KEY_REQUIRED,
|
|
391
|
+
"Access key required. Set ALCHEMY_ACCESS_KEY or run 'alchemy config set access-key <key>'.",
|
|
392
|
+
"Get an access key: https://www.alchemy.com/docs/reference/admin-api/overview"
|
|
393
|
+
);
|
|
474
394
|
}
|
|
475
|
-
function
|
|
476
|
-
|
|
477
|
-
|
|
395
|
+
function errInvalidAPIKey(details) {
|
|
396
|
+
return new CLIError(
|
|
397
|
+
ErrorCode.INVALID_API_KEY,
|
|
398
|
+
"Invalid API key. Check your key and try again.",
|
|
399
|
+
"alchemy config set app",
|
|
400
|
+
details
|
|
401
|
+
);
|
|
478
402
|
}
|
|
479
|
-
function
|
|
480
|
-
|
|
403
|
+
function errNetworkNotEnabled(network, details) {
|
|
404
|
+
const networkLabel = network.toLowerCase().replace(/_/g, "-");
|
|
405
|
+
return new CLIError(
|
|
406
|
+
ErrorCode.NETWORK_NOT_ENABLED,
|
|
407
|
+
`API key is valid, but ${networkLabel} is not enabled for this app.`,
|
|
408
|
+
void 0,
|
|
409
|
+
details
|
|
410
|
+
);
|
|
481
411
|
}
|
|
482
|
-
function
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
412
|
+
function errNetwork(detail) {
|
|
413
|
+
return new CLIError(
|
|
414
|
+
ErrorCode.NETWORK_ERROR,
|
|
415
|
+
`Network error: ${detail}`,
|
|
416
|
+
"Check your internet connection and try again."
|
|
417
|
+
);
|
|
488
418
|
}
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
419
|
+
var RPC_ERROR_HINTS = {
|
|
420
|
+
[-32700]: "Parse error. The request JSON is malformed.",
|
|
421
|
+
[-32600]: "Invalid request. Check the JSON-RPC request format.",
|
|
422
|
+
[-32601]: "Method not supported. Check the method name and ensure your plan supports it.",
|
|
423
|
+
[-32602]: "Invalid parameters. Check argument types and format.",
|
|
424
|
+
[-32603]: "Internal JSON-RPC error."
|
|
425
|
+
};
|
|
426
|
+
function errRPC(code, message) {
|
|
427
|
+
const hint = RPC_ERROR_HINTS[code];
|
|
428
|
+
return new CLIError(ErrorCode.RPC_ERROR, `RPC error ${code}: ${message}`, hint);
|
|
429
|
+
}
|
|
430
|
+
function errInvalidArgs(detail) {
|
|
431
|
+
return new CLIError(ErrorCode.INVALID_ARGS, detail);
|
|
432
|
+
}
|
|
433
|
+
function errNotFound(resource) {
|
|
434
|
+
return new CLIError(ErrorCode.NOT_FOUND, `Not found: ${resource}`);
|
|
435
|
+
}
|
|
436
|
+
function errRateLimited() {
|
|
437
|
+
return new CLIError(
|
|
438
|
+
ErrorCode.RATE_LIMITED,
|
|
439
|
+
"Rate limited. Please wait and try again.",
|
|
440
|
+
"Consider upgrading your Alchemy plan for higher rate limits."
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
function errInvalidAccessKey() {
|
|
444
|
+
return new CLIError(
|
|
445
|
+
ErrorCode.INVALID_ACCESS_KEY,
|
|
446
|
+
"Invalid access key. Check your key and try again.",
|
|
447
|
+
"Get an access key: https://www.alchemy.com/docs/reference/admin-api/overview"
|
|
448
|
+
);
|
|
449
|
+
}
|
|
450
|
+
function errAccessDenied(detail) {
|
|
451
|
+
const message = detail ? `Access denied: ${detail}` : "Access denied. Your access key may not have permission for this operation.";
|
|
452
|
+
return new CLIError(
|
|
453
|
+
ErrorCode.INVALID_ACCESS_KEY,
|
|
454
|
+
message,
|
|
455
|
+
"Check your account tier and feature access at https://dashboard.alchemy.com/"
|
|
456
|
+
);
|
|
457
|
+
}
|
|
458
|
+
function errAppRequired() {
|
|
459
|
+
return new CLIError(
|
|
460
|
+
ErrorCode.APP_REQUIRED,
|
|
461
|
+
"No app selected. Set an app to resolve the API key automatically.",
|
|
462
|
+
"alchemy config set app <app-id>"
|
|
463
|
+
);
|
|
464
|
+
}
|
|
465
|
+
function errWalletKeyRequired() {
|
|
466
|
+
return new CLIError(
|
|
467
|
+
ErrorCode.AUTH_REQUIRED,
|
|
468
|
+
"Wallet key required for x402. Set ALCHEMY_WALLET_KEY, run 'alchemy wallet connect --mode local --chain evm', or use --wallet-key-file.",
|
|
469
|
+
"alchemy wallet connect --mode local --chain evm"
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
function errSessionExpired() {
|
|
473
|
+
return new CLIError(
|
|
474
|
+
ErrorCode.AUTH_REQUIRED,
|
|
475
|
+
"Your wallet session has expired or been revoked.",
|
|
476
|
+
"alchemy wallet connect --force"
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
function errNoActiveSession() {
|
|
480
|
+
return new CLIError(
|
|
481
|
+
ErrorCode.AUTH_REQUIRED,
|
|
482
|
+
"No active wallet session. Session signing was requested but no session is connected.",
|
|
483
|
+
"alchemy wallet connect"
|
|
484
|
+
);
|
|
485
|
+
}
|
|
486
|
+
function errSolanaWalletKeyRequired() {
|
|
487
|
+
return new CLIError(
|
|
488
|
+
ErrorCode.AUTH_REQUIRED,
|
|
489
|
+
"Solana wallet key required. Set ALCHEMY_SOLANA_WALLET_KEY, run 'alchemy wallet connect --mode local --chain solana', or use --solana-wallet-key-file.",
|
|
490
|
+
"alchemy wallet connect --mode local --chain solana"
|
|
491
|
+
);
|
|
492
|
+
}
|
|
493
|
+
function errSolanaTransactionFailed(details) {
|
|
494
|
+
return new CLIError(
|
|
495
|
+
ErrorCode.RPC_ERROR,
|
|
496
|
+
"Solana transaction failed.",
|
|
497
|
+
void 0,
|
|
498
|
+
details
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
function errAdminAPI(status, message) {
|
|
502
|
+
return new CLIError(
|
|
503
|
+
ErrorCode.ADMIN_API_ERROR,
|
|
504
|
+
`Admin API error (HTTP ${status}): ${message}`
|
|
505
|
+
);
|
|
506
|
+
}
|
|
507
|
+
function errSetupRequired(data) {
|
|
508
|
+
return new CLIError(
|
|
509
|
+
ErrorCode.SETUP_REQUIRED,
|
|
510
|
+
"Setup required before running in non-interactive mode.",
|
|
511
|
+
"Run 'alchemy' in a TTY for guided onboarding, or run 'alchemy config status --json' for machine-readable remediation steps.",
|
|
512
|
+
void 0,
|
|
513
|
+
data
|
|
514
|
+
);
|
|
515
|
+
}
|
|
516
|
+
var replMode = false;
|
|
517
|
+
function setReplMode(enabled) {
|
|
518
|
+
replMode = enabled;
|
|
519
|
+
}
|
|
520
|
+
function exitWithError(err) {
|
|
521
|
+
const cliErr = err instanceof CLIError ? err : new CLIError(
|
|
522
|
+
ErrorCode.INTERNAL_ERROR,
|
|
523
|
+
err instanceof Error ? err.message : String(err)
|
|
524
|
+
);
|
|
525
|
+
printError(cliErr);
|
|
526
|
+
if (replMode) {
|
|
527
|
+
throw cliErr;
|
|
492
528
|
}
|
|
529
|
+
process.exit(EXIT_CODES[cliErr.code]);
|
|
493
530
|
}
|
|
494
531
|
|
|
495
532
|
export {
|
|
@@ -529,6 +566,10 @@ export {
|
|
|
529
566
|
errAccessDenied,
|
|
530
567
|
errAppRequired,
|
|
531
568
|
errWalletKeyRequired,
|
|
569
|
+
errSessionExpired,
|
|
570
|
+
errNoActiveSession,
|
|
571
|
+
errSolanaWalletKeyRequired,
|
|
572
|
+
errSolanaTransactionFailed,
|
|
532
573
|
errAdminAPI,
|
|
533
574
|
errSetupRequired,
|
|
534
575
|
setReplMode,
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
|
|
3
|
+
import {
|
|
4
|
+
CLIError,
|
|
5
|
+
EXIT_CODES,
|
|
6
|
+
ErrorCode,
|
|
7
|
+
errAccessDenied,
|
|
8
|
+
errAccessKeyRequired,
|
|
9
|
+
errAdminAPI,
|
|
10
|
+
errAppRequired,
|
|
11
|
+
errAuthRequired,
|
|
12
|
+
errInvalidAPIKey,
|
|
13
|
+
errInvalidAccessKey,
|
|
14
|
+
errInvalidArgs,
|
|
15
|
+
errNetwork,
|
|
16
|
+
errNetworkNotEnabled,
|
|
17
|
+
errNoActiveSession,
|
|
18
|
+
errNotFound,
|
|
19
|
+
errRPC,
|
|
20
|
+
errRateLimited,
|
|
21
|
+
errSessionExpired,
|
|
22
|
+
errSetupRequired,
|
|
23
|
+
errSolanaTransactionFailed,
|
|
24
|
+
errSolanaWalletKeyRequired,
|
|
25
|
+
errWalletKeyRequired,
|
|
26
|
+
exitWithError,
|
|
27
|
+
setReplMode
|
|
28
|
+
} from "./chunk-QEDAULQ2.js";
|
|
29
|
+
export {
|
|
30
|
+
CLIError,
|
|
31
|
+
EXIT_CODES,
|
|
32
|
+
ErrorCode,
|
|
33
|
+
errAccessDenied,
|
|
34
|
+
errAccessKeyRequired,
|
|
35
|
+
errAdminAPI,
|
|
36
|
+
errAppRequired,
|
|
37
|
+
errAuthRequired,
|
|
38
|
+
errInvalidAPIKey,
|
|
39
|
+
errInvalidAccessKey,
|
|
40
|
+
errInvalidArgs,
|
|
41
|
+
errNetwork,
|
|
42
|
+
errNetworkNotEnabled,
|
|
43
|
+
errNoActiveSession,
|
|
44
|
+
errNotFound,
|
|
45
|
+
errRPC,
|
|
46
|
+
errRateLimited,
|
|
47
|
+
errSessionExpired,
|
|
48
|
+
errSetupRequired,
|
|
49
|
+
errSolanaTransactionFailed,
|
|
50
|
+
errSolanaWalletKeyRequired,
|
|
51
|
+
errWalletKeyRequired,
|
|
52
|
+
exitWithError,
|
|
53
|
+
setReplMode
|
|
54
|
+
};
|