@alchemy/cli 0.10.0 → 0.11.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.
@@ -4,22 +4,21 @@ import {
4
4
  configDir,
5
5
  load,
6
6
  save
7
- } from "./chunk-GLKB4JM7.js";
7
+ } from "./chunk-LANOFNO6.js";
8
8
  import {
9
9
  CLIError,
10
10
  ErrorCode,
11
11
  debug,
12
12
  errAccessDenied,
13
- errAccessKeyRequired,
14
13
  errAdminAPI,
15
14
  errAppRequired,
16
15
  errAuthRequired,
17
16
  errInvalidAPIKey,
18
- errInvalidAccessKey,
19
17
  errInvalidArgs,
20
18
  errLoginRequired,
21
19
  errNetwork,
22
20
  errNetworkNotEnabled,
21
+ errNetworkRequired,
23
22
  errNotFound,
24
23
  errRPC,
25
24
  errRateLimited,
@@ -31,7 +30,7 @@ import {
31
30
  redactSensitiveText,
32
31
  timeout,
33
32
  verbose
34
- } from "./chunk-CTTW4PA4.js";
33
+ } from "./chunk-5BEJA752.js";
35
34
 
36
35
  // src/lib/resolve.ts
37
36
  import { readFileSync as readFileSync2 } from "fs";
@@ -625,6 +624,11 @@ var Client = class _Client {
625
624
  if (networkNotEnabled) return networkNotEnabled;
626
625
  return errInvalidAPIKey(detail || void 0);
627
626
  }
627
+ isWrappedNetworkFailure(err) {
628
+ return err.status === void 0 && err.code === -32e3 && /\b(fetch failed|failed to fetch|network error|econnrefused|enotfound|etimedout|eai_again|socket hang up)\b/i.test(
629
+ err.message
630
+ );
631
+ }
628
632
  tryParseRPCError(text) {
629
633
  try {
630
634
  const parsed = JSON.parse(text);
@@ -635,6 +639,9 @@ var Client = class _Client {
635
639
  }
636
640
  return null;
637
641
  }
642
+ isFetchFailureError(err) {
643
+ return err.status === void 0 && err.message.trim().toLowerCase() === "fetch failed";
644
+ }
638
645
  verboseLog(message) {
639
646
  if (verbose) {
640
647
  process.stderr.write(`[verbose] ${message}
@@ -671,6 +678,9 @@ var Client = class _Client {
671
678
  if (err.status !== void 0) {
672
679
  throw errNetwork(`HTTP ${err.status}: ${err.message}`);
673
680
  }
681
+ if (this.isWrappedNetworkFailure(err)) {
682
+ throw errNetwork(err.message);
683
+ }
674
684
  throw errRPC(err.code, err.message);
675
685
  }
676
686
  throw err;
@@ -945,17 +955,10 @@ var AdminClient = class _AdminClient {
945
955
  static ADMIN_API_BASE_URL_ENV = "ALCHEMY_ADMIN_API_BASE_URL";
946
956
  credential;
947
957
  constructor(credential) {
948
- if (typeof credential === "string") {
949
- this.validateAccessKey(credential);
950
- this.credential = { type: "access_key", key: credential };
951
- } else {
952
- if (credential.type === "access_key") {
953
- this.validateAccessKey(credential.key);
954
- } else if (!credential.token.trim()) {
955
- throw errAuthRequired();
956
- }
957
- this.credential = credential;
958
+ if (!credential.token.trim()) {
959
+ throw errLoginRequired();
958
960
  }
961
+ this.credential = credential;
959
962
  }
960
963
  baseURL() {
961
964
  const override = this.baseURLOverride();
@@ -976,11 +979,6 @@ var AdminClient = class _AdminClient {
976
979
  allowedHostnames: [STAGING_ADMIN_API_HOST]
977
980
  });
978
981
  }
979
- validateAccessKey(accessKey) {
980
- if (!accessKey.trim() || /\s/.test(accessKey)) {
981
- throw errInvalidAccessKey();
982
- }
983
- }
984
982
  assertSafeRequestTarget(url) {
985
983
  let parsed;
986
984
  try {
@@ -1003,7 +1001,7 @@ var AdminClient = class _AdminClient {
1003
1001
  method,
1004
1002
  redirect: "error",
1005
1003
  headers: {
1006
- Authorization: `Bearer ${this.credential.type === "access_key" ? this.credential.key : this.credential.token}`,
1004
+ Authorization: `Bearer ${this.credential.token}`,
1007
1005
  "Content-Type": "application/json",
1008
1006
  Accept: "application/json"
1009
1007
  },
@@ -1011,7 +1009,7 @@ var AdminClient = class _AdminClient {
1011
1009
  });
1012
1010
  if (resp.status === 401) {
1013
1011
  debug(`401 Unauthorized from ${url}`);
1014
- throw errInvalidAccessKey();
1012
+ throw errLoginRequired();
1015
1013
  }
1016
1014
  if (resp.status === 403) {
1017
1015
  const detail = await resp.text().catch(() => "");
@@ -1127,17 +1125,10 @@ var GasManagerClient = class _GasManagerClient {
1127
1125
  static BASE_URL_ENV = "ALCHEMY_GAS_MANAGER_BASE_URL";
1128
1126
  credential;
1129
1127
  constructor(credential) {
1130
- if (typeof credential === "string") {
1131
- this.validateAccessKey(credential);
1132
- this.credential = { type: "access_key", key: credential };
1133
- } else {
1134
- if (credential.type === "access_key") {
1135
- this.validateAccessKey(credential.key);
1136
- } else if (!credential.token.trim()) {
1137
- throw errAuthRequired();
1138
- }
1139
- this.credential = credential;
1128
+ if (!credential.token.trim()) {
1129
+ throw errLoginRequired();
1140
1130
  }
1131
+ this.credential = credential;
1141
1132
  }
1142
1133
  baseURL() {
1143
1134
  const override = this.baseURLOverride();
@@ -1156,11 +1147,6 @@ var GasManagerClient = class _GasManagerClient {
1156
1147
  baseURLOverride() {
1157
1148
  return parseBaseURLOverride(_GasManagerClient.BASE_URL_ENV);
1158
1149
  }
1159
- validateAccessKey(accessKey) {
1160
- if (!accessKey.trim() || /\s/.test(accessKey)) {
1161
- throw errInvalidAccessKey();
1162
- }
1163
- }
1164
1150
  assertSafeRequestTarget(url) {
1165
1151
  let parsed;
1166
1152
  try {
@@ -1179,19 +1165,18 @@ var GasManagerClient = class _GasManagerClient {
1179
1165
  const url = `${this.baseURL()}${path}`;
1180
1166
  debug(`${method} ${url}`);
1181
1167
  this.assertSafeRequestTarget(url);
1182
- const token = this.credential.type === "access_key" ? this.credential.key : this.credential.token;
1183
1168
  const resp = await fetchWithTimeout(url, {
1184
1169
  method,
1185
1170
  redirect: "error",
1186
1171
  headers: {
1187
- Authorization: `Bearer ${token}`,
1172
+ Authorization: `Bearer ${this.credential.token}`,
1188
1173
  "Content-Type": "application/json",
1189
1174
  Accept: "application/json"
1190
1175
  },
1191
1176
  ...body !== void 0 && { body: JSON.stringify(body) }
1192
1177
  });
1193
1178
  if (resp.status === 401) {
1194
- throw this.credential.type === "auth_token" ? errLoginRequired() : errInvalidAccessKey();
1179
+ throw errLoginRequired();
1195
1180
  }
1196
1181
  if (resp.status === 403) {
1197
1182
  const detail = await resp.text().catch(() => "");
@@ -1202,15 +1187,12 @@ var GasManagerClient = class _GasManagerClient {
1202
1187
  } catch {
1203
1188
  reason = detail || void 0;
1204
1189
  }
1205
- if (this.credential.type === "auth_token") {
1206
- const tail = reason ? ` (${reason})` : "";
1207
- throw new CLIError(
1208
- ErrorCode.AUTH_REQUIRED,
1209
- `Access denied for this Alchemy account or app${tail}. Re-authenticate with 'alchemy auth login' or check that the default app is one you have permission to manage.`,
1210
- "alchemy auth login"
1211
- );
1212
- }
1213
- throw errAccessDenied(typeof reason === "string" ? reason : void 0);
1190
+ const tail = reason ? ` (${reason})` : "";
1191
+ throw new CLIError(
1192
+ ErrorCode.AUTH_REQUIRED,
1193
+ `Access denied for this Alchemy account or app${tail}. Re-authenticate with 'alchemy auth login' or check that the default app is one you have permission to manage.`,
1194
+ "alchemy auth login"
1195
+ );
1214
1196
  }
1215
1197
  if (resp.status === 404) {
1216
1198
  const text = await resp.text().catch(() => "");
@@ -1569,43 +1551,29 @@ function resolveAPIKey(program, cfg) {
1569
1551
  if (config.app?.apiKey) return config.app.apiKey;
1570
1552
  return void 0;
1571
1553
  }
1572
- function resolveAccessKey(_program, cfg) {
1573
- if (process.env.ALCHEMY_ACCESS_KEY) return process.env.ALCHEMY_ACCESS_KEY;
1574
- const config = cfg ?? load();
1575
- if (config.access_key) return config.access_key;
1576
- return void 0;
1577
- }
1578
- function resolveNetwork(program, cfg, defaultNetwork) {
1554
+ function resolveOptionalNetwork(program) {
1579
1555
  const opts = getCommandOptions(program);
1580
- if (opts.network) return opts.network;
1581
- if (process.env.ALCHEMY_NETWORK) return process.env.ALCHEMY_NETWORK;
1582
- const config = cfg ?? load();
1583
- if (config.network) return config.network;
1584
- return defaultNetwork ?? "eth-mainnet";
1556
+ return opts.network;
1585
1557
  }
1586
- function resolveSolanaNetwork(program, cfg) {
1587
- const opts = getCommandOptions(program);
1588
- if (opts.network) {
1589
- if (!isSolanaNetwork(opts.network)) {
1590
- throw errInvalidArgs(
1591
- `Network '${opts.network}' is not a Solana network. Use a solana-* network with the solana namespace.`
1592
- );
1593
- }
1594
- return opts.network;
1595
- }
1596
- if (process.env.ALCHEMY_NETWORK) {
1597
- if (!isSolanaNetwork(process.env.ALCHEMY_NETWORK)) {
1598
- throw errInvalidArgs(
1599
- `ALCHEMY_NETWORK='${process.env.ALCHEMY_NETWORK}' is not a Solana network. Use a solana-* network with the solana namespace.`
1600
- );
1601
- }
1602
- return process.env.ALCHEMY_NETWORK;
1558
+ function resolveNetwork(program) {
1559
+ const network = resolveOptionalNetwork(program);
1560
+ if (network) return network;
1561
+ throw errNetworkRequired();
1562
+ }
1563
+ function resolveRequiredNetwork(program) {
1564
+ return resolveNetwork(program);
1565
+ }
1566
+ function resolveSolanaNetwork(program) {
1567
+ const network = resolveOptionalNetwork(program);
1568
+ if (!network) {
1569
+ throw errNetworkRequired("alchemy solana network list");
1603
1570
  }
1604
- const config = cfg ?? load();
1605
- if (config.network && isSolanaNetwork(config.network)) {
1606
- return config.network;
1571
+ if (!isSolanaNetwork(network)) {
1572
+ throw errInvalidArgs(
1573
+ `Network '${network}' is not a Solana network. Use a solana-* network with the solana namespace.`
1574
+ );
1607
1575
  }
1608
- return "solana-mainnet";
1576
+ return network;
1609
1577
  }
1610
1578
  function resolveAppId(program, cfg) {
1611
1579
  const opts = getCommandOptions(program);
@@ -1627,11 +1595,9 @@ function resolveAuthToken(cfg) {
1627
1595
  }
1628
1596
  function adminClientFromFlags(program) {
1629
1597
  const cfg = load();
1630
- const accessKey = resolveAccessKey(program, cfg);
1631
- if (accessKey) return new AdminClient(accessKey);
1632
1598
  const authToken = resolveAuthToken(cfg);
1633
1599
  if (authToken) return new AdminClient({ type: "auth_token", token: authToken });
1634
- throw errAccessKeyRequired();
1600
+ throw errLoginRequired();
1635
1601
  }
1636
1602
  function hasAuthLoginToken(cfg) {
1637
1603
  return Boolean(resolveAuthToken(cfg));
@@ -1653,7 +1619,7 @@ function resolveX402Client(program) {
1653
1619
  if (!resolveX402(program, cfg)) return null;
1654
1620
  const walletKey = resolveWalletKey(program, cfg);
1655
1621
  if (!walletKey) return null;
1656
- return new X402Client(walletKey, resolveNetwork(program, cfg));
1622
+ return new X402Client(walletKey, resolveNetwork(program));
1657
1623
  }
1658
1624
  function resolveWalletKey(program, cfg) {
1659
1625
  const opts = getCommandOptions(program);
@@ -1743,9 +1709,20 @@ function resolveActiveSigner(program, cfg) {
1743
1709
  function resolveDelegatedMode(program, cfg) {
1744
1710
  return resolveActiveSigner(program, cfg) === "session";
1745
1711
  }
1712
+ function resolveClientNetwork(program, opts) {
1713
+ return opts?.forceNetwork ?? resolveNetwork(program);
1714
+ }
1715
+ function apiKeyClientFromFlags(program, opts) {
1716
+ const cfg = load();
1717
+ const network = resolveClientNetwork(program, opts);
1718
+ debug(`using network=${network}`);
1719
+ const apiKey = resolveAPIKey(program, cfg);
1720
+ if (!apiKey) throw errAuthRequired();
1721
+ return new Client(apiKey, network);
1722
+ }
1746
1723
  function clientFromFlags(program, opts) {
1747
1724
  const cfg = load();
1748
- const network = opts?.forceNetwork ?? resolveNetwork(program, cfg, opts?.defaultNetwork);
1725
+ const network = resolveClientNetwork(program, opts);
1749
1726
  debug(`using network=${network}`);
1750
1727
  if (resolveX402(program, cfg)) {
1751
1728
  const walletKey = resolveWalletKey(program, cfg);
@@ -1807,8 +1784,9 @@ export {
1807
1784
  isSessionValid,
1808
1785
  getWalletSessionByChain,
1809
1786
  resolveAPIKey,
1810
- resolveAccessKey,
1787
+ resolveOptionalNetwork,
1811
1788
  resolveNetwork,
1789
+ resolveRequiredNetwork,
1812
1790
  resolveSolanaNetwork,
1813
1791
  resolveAppId,
1814
1792
  resolveAuthToken,
@@ -1825,6 +1803,7 @@ export {
1825
1803
  resolveSolanaFeePolicyId,
1826
1804
  resolveActiveSigner,
1827
1805
  resolveDelegatedMode,
1806
+ apiKeyClientFromFlags,
1828
1807
  clientFromFlags,
1829
1808
  resolveConfiguredNetworkSlugs,
1830
1809
  resolveWalletSession,
@@ -2,11 +2,11 @@
2
2
  if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
3
3
  import {
4
4
  isInteractiveAllowed
5
- } from "./chunk-3GBDYROJ.js";
5
+ } from "./chunk-RPSHRYCZ.js";
6
6
  import {
7
7
  resolveAuthToken,
8
8
  resolveWalletSession
9
- } from "./chunk-ANONMDDZ.js";
9
+ } from "./chunk-OL5MEN62.js";
10
10
 
11
11
  // src/lib/onboarding.ts
12
12
  var SETUP_CAPABILITY_ORDER = [
@@ -26,9 +26,6 @@ var SETUP_CAPABILITY_LABELS = {
26
26
  function hasAPIKey(cfg) {
27
27
  return Boolean(cfg.api_key?.trim());
28
28
  }
29
- function hasAccessKeyAndApp(cfg) {
30
- return Boolean(cfg.access_key?.trim() && cfg.app?.id && cfg.app.apiKey);
31
- }
32
29
  function hasX402Wallet(cfg) {
33
30
  return cfg.x402 === true && Boolean(cfg.wallet_key_file?.trim());
34
31
  }
@@ -40,7 +37,7 @@ function capabilityStatus(args) {
40
37
  }
41
38
  function getSetupCapabilities(cfg) {
42
39
  const hasConfiguredAPIKey = hasAPIKey(cfg) || Boolean(cfg.app?.apiKey?.trim());
43
- const hasAdminAuth = Boolean(cfg.access_key?.trim()) || hasAuthToken(cfg);
40
+ const hasAdminAuth = hasAuthToken(cfg);
44
41
  const hasNotifyAuth = Boolean(
45
42
  cfg.webhook_api_key?.trim() || cfg.app?.webhookApiKey?.trim()
46
43
  );
@@ -58,9 +55,9 @@ function getSetupCapabilities(cfg) {
58
55
  }),
59
56
  admin_api: capabilityStatus({
60
57
  complete: hasAdminAuth,
61
- satisfiedBy: cfg.access_key?.trim() ? "access_key" : hasAuthToken(cfg) ? "auth_token" : null,
62
- missing: hasAdminAuth ? [] : ["access-key or auth token"],
63
- nextCommands: hasAdminAuth ? [] : ["alchemy auth", "alchemy config set access-key <key>"]
58
+ satisfiedBy: hasAdminAuth ? "auth_token" : null,
59
+ missing: hasAdminAuth ? [] : ["auth token"],
60
+ nextCommands: hasAdminAuth ? [] : ["alchemy auth"]
64
61
  }),
65
62
  notify_webhooks: capabilityStatus({
66
63
  complete: hasNotifyAuth,
@@ -87,7 +84,6 @@ function getSetupCapabilities(cfg) {
87
84
  }
88
85
  function getSetupMethod(cfg) {
89
86
  if (hasAPIKey(cfg)) return "api_key";
90
- if (hasAccessKeyAndApp(cfg)) return "access_key_app";
91
87
  if (hasX402Wallet(cfg)) return "x402_wallet";
92
88
  if (hasAuthToken(cfg)) return "auth_token";
93
89
  return null;
@@ -110,11 +106,10 @@ function getSetupStatus(cfg) {
110
106
  return {
111
107
  complete: false,
112
108
  satisfiedBy: null,
113
- missing: ["Provide one auth path: alchemy auth OR api-key OR ALCHEMY_ACCESS_KEY+app OR SIWx wallet"],
109
+ missing: ["Provide one auth path: alchemy auth OR api-key OR SIWx wallet"],
114
110
  nextCommands: [
115
111
  "alchemy auth",
116
112
  "alchemy config set app",
117
- "alchemy config set access-key <key> && alchemy config set app <app-id>",
118
113
  "alchemy wallet connect --mode local && alchemy config set x402 true"
119
114
  ],
120
115
  capabilities
@@ -2,7 +2,7 @@
2
2
  if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
3
3
  import {
4
4
  isJSONMode
5
- } from "./chunk-CTTW4PA4.js";
5
+ } from "./chunk-5BEJA752.js";
6
6
 
7
7
  // src/lib/interaction.ts
8
8
  import { stdin, stdout } from "process";
@@ -2,10 +2,10 @@
2
2
  if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
3
3
  import {
4
4
  configPath
5
- } from "./chunk-GLKB4JM7.js";
5
+ } from "./chunk-LANOFNO6.js";
6
6
  import {
7
7
  esc
8
- } from "./chunk-CTTW4PA4.js";
8
+ } from "./chunk-5BEJA752.js";
9
9
 
10
10
  // src/lib/update-check.ts
11
11
  import { execFileSync } from "child_process";
@@ -53,7 +53,7 @@ function semverLT(a, b) {
53
53
  return false;
54
54
  }
55
55
  function currentVersion() {
56
- return true ? "0.10.0" : "0.0.0";
56
+ return true ? "0.11.1" : "0.0.0";
57
57
  }
58
58
  function toUpdateStatus(latestVersion, checkedAt) {
59
59
  const current = currentVersion();
@@ -5,16 +5,15 @@ import {
5
5
  EXIT_CODES,
6
6
  ErrorCode,
7
7
  errAccessDenied,
8
- errAccessKeyRequired,
9
8
  errAdminAPI,
10
9
  errAppRequired,
11
10
  errAuthRequired,
12
11
  errInvalidAPIKey,
13
- errInvalidAccessKey,
14
12
  errInvalidArgs,
15
13
  errLoginRequired,
16
14
  errNetwork,
17
15
  errNetworkNotEnabled,
16
+ errNetworkRequired,
18
17
  errNoActiveSession,
19
18
  errNotFound,
20
19
  errRPC,
@@ -24,25 +23,25 @@ import {
24
23
  errSolanaTransactionFailed,
25
24
  errSolanaWalletKeyRequired,
26
25
  errWalletKeyRequired,
26
+ errWalletRequired,
27
27
  exitWithError,
28
28
  isReplMode,
29
29
  setReplMode
30
- } from "./chunk-CTTW4PA4.js";
30
+ } from "./chunk-5BEJA752.js";
31
31
  export {
32
32
  CLIError,
33
33
  EXIT_CODES,
34
34
  ErrorCode,
35
35
  errAccessDenied,
36
- errAccessKeyRequired,
37
36
  errAdminAPI,
38
37
  errAppRequired,
39
38
  errAuthRequired,
40
39
  errInvalidAPIKey,
41
- errInvalidAccessKey,
42
40
  errInvalidArgs,
43
41
  errLoginRequired,
44
42
  errNetwork,
45
43
  errNetworkNotEnabled,
44
+ errNetworkRequired,
46
45
  errNoActiveSession,
47
46
  errNotFound,
48
47
  errRPC,
@@ -52,6 +51,7 @@ export {
52
51
  errSolanaTransactionFailed,
53
52
  errSolanaWalletKeyRequired,
54
53
  errWalletKeyRequired,
54
+ errWalletRequired,
55
55
  exitWithError,
56
56
  isReplMode,
57
57
  setReplMode