@alchemy/cli 0.9.2 → 0.9.3

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/dist/index.js CHANGED
@@ -5,32 +5,35 @@ import {
5
5
  errNotLoggedInForPolicyLookup,
6
6
  errSponsorshipNeedsPolicy,
7
7
  selectOrCreatePolicy
8
- } from "./chunk-TTWOBNJP.js";
8
+ } from "./chunk-D2RUM2DD.js";
9
9
  import {
10
10
  registerAuth
11
- } from "./chunk-L2WODD2D.js";
11
+ } from "./chunk-L5E7GEUU.js";
12
12
  import {
13
13
  openBrowser
14
- } from "./chunk-RGVM5SNE.js";
14
+ } from "./chunk-AMGGO36F.js";
15
15
  import {
16
16
  SETUP_CAPABILITY_LABELS,
17
17
  SETUP_CAPABILITY_ORDER,
18
18
  getSetupStatus,
19
19
  isSetupComplete,
20
20
  shouldRunOnboarding
21
- } from "./chunk-P56HOTPV.js";
21
+ } from "./chunk-VN5JUWHO.js";
22
22
  import {
23
23
  isInteractiveAllowed
24
- } from "./chunk-75ICFV5K.js";
24
+ } from "./chunk-3GBDYROJ.js";
25
25
  import {
26
+ RpcApiError,
26
27
  adminClientFromFlags,
27
28
  clearSession,
28
29
  clientFromFlags,
29
30
  createPendingSession,
30
31
  fromAdminNetworkId,
31
32
  gasManagerClientFromFlags,
33
+ getGatewayDomain,
32
34
  getRPCNetworks,
33
35
  getWalletSessionByChain,
36
+ globalRpcCall,
34
37
  hasAuthLoginToken,
35
38
  isSessionValid,
36
39
  isSolanaNetwork,
@@ -52,14 +55,17 @@ import {
52
55
  resolveWalletSession,
53
56
  resolveX402Client,
54
57
  saveSession,
58
+ supportedWalletNetworks,
55
59
  toAdminNetworkId,
56
- updateSession
57
- } from "./chunk-SIIZGMK5.js";
60
+ updateSession,
61
+ validateNetwork,
62
+ walletNetworkToChain
63
+ } from "./chunk-ANONMDDZ.js";
58
64
  import {
59
65
  getAvailableUpdate,
60
66
  getUpdateStatus,
61
67
  printUpdateNotice
62
- } from "./chunk-HGFU4JCS.js";
68
+ } from "./chunk-NUSUQI7X.js";
63
69
  import {
64
70
  bold,
65
71
  brand,
@@ -83,7 +89,7 @@ import {
83
89
  weiToEth,
84
90
  withSpinner,
85
91
  yellow
86
- } from "./chunk-MV7O3XBG.js";
92
+ } from "./chunk-PMNRIXJI.js";
87
93
  import {
88
94
  KEY_MAP,
89
95
  configDir,
@@ -94,7 +100,7 @@ import {
94
100
  save,
95
101
  toMap,
96
102
  validKeys
97
- } from "./chunk-GDLPBPG3.js";
103
+ } from "./chunk-GLKB4JM7.js";
98
104
  import {
99
105
  CLIError,
100
106
  EXIT_CODES,
@@ -107,6 +113,7 @@ import {
107
113
  errNetwork,
108
114
  errNoActiveSession,
109
115
  errNotFound,
116
+ errRPC,
110
117
  errRateLimited,
111
118
  errSessionExpired,
112
119
  errSetupRequired,
@@ -129,8 +136,9 @@ import {
129
136
  quiet,
130
137
  setFlags,
131
138
  setNoColor,
139
+ timeout,
132
140
  verbose
133
- } from "./chunk-OVLQH6KL.js";
141
+ } from "./chunk-CTTW4PA4.js";
134
142
 
135
143
  // src/index.ts
136
144
  import { Command, Help } from "commander";
@@ -577,8 +585,8 @@ function registerConfig(program2) {
577
585
  "Interactive policy selection requires an interactive terminal. Pass an ID: `alchemy config set evm-gas-policy-id <id>`."
578
586
  );
579
587
  }
580
- const { selectOrCreatePolicy: selectOrCreatePolicy2 } = await import("./policy-prompt-4BV5AWVV.js");
581
- const { resolveNetwork: resolveNetwork2 } = await import("./resolve-FQ66OWT7.js");
588
+ const { selectOrCreatePolicy: selectOrCreatePolicy2 } = await import("./policy-prompt-V6W7CPAO.js");
589
+ const { resolveNetwork: resolveNetwork2 } = await import("./resolve-REZCFZZ7.js");
582
590
  const network = resolveNetwork2(program2);
583
591
  await selectOrCreatePolicy2({
584
592
  flavor: "sponsorship",
@@ -632,8 +640,8 @@ function registerConfig(program2) {
632
640
  "Interactive policy selection requires an interactive terminal. Pass an ID: `alchemy config set solana-fee-policy-id <id>`."
633
641
  );
634
642
  }
635
- const { selectOrCreatePolicy: selectOrCreatePolicy2 } = await import("./policy-prompt-4BV5AWVV.js");
636
- const { resolveSolanaNetwork: resolveSolanaNetwork2 } = await import("./resolve-FQ66OWT7.js");
643
+ const { selectOrCreatePolicy: selectOrCreatePolicy2 } = await import("./policy-prompt-V6W7CPAO.js");
644
+ const { resolveSolanaNetwork: resolveSolanaNetwork2 } = await import("./resolve-REZCFZZ7.js");
637
645
  const network = resolveSolanaNetwork2(program2);
638
646
  await selectOrCreatePolicy2({
639
647
  flavor: "solana",
@@ -691,7 +699,7 @@ function registerConfig(program2) {
691
699
  printJSON(toMap(cfg));
692
700
  return;
693
701
  }
694
- const { resolveAuthToken: resolveAuthToken2 } = await import("./resolve-FQ66OWT7.js");
702
+ const { resolveAuthToken: resolveAuthToken2 } = await import("./resolve-REZCFZZ7.js");
695
703
  const validToken = resolveAuthToken2(cfg);
696
704
  const authStatus = cfg.auth_token ? validToken ? `${green("\u2713")} authenticated${cfg.auth_token_expires_at ? ` ${dim(`(expires ${cfg.auth_token_expires_at})`)}` : ""}` : `${yellow("\u25C6")} expired${cfg.auth_token_expires_at ? ` ${dim(`(${cfg.auth_token_expires_at})`)}` : ""}` : dim("(not set) \u2014 run 'alchemy auth' to log in");
697
705
  const pairs = [
@@ -1924,10 +1932,10 @@ function createInterruptibleDelay(ms, signal) {
1924
1932
  }
1925
1933
  return new Promise((resolve, reject) => {
1926
1934
  const onAbort = () => {
1927
- clearTimeout(timeout);
1935
+ clearTimeout(timeout2);
1928
1936
  reject(new WalletConnectInterruptedError());
1929
1937
  };
1930
- const timeout = setTimeout(() => {
1938
+ const timeout2 = setTimeout(() => {
1931
1939
  signal.removeEventListener("abort", onAbort);
1932
1940
  resolve();
1933
1941
  }, ms);
@@ -2568,25 +2576,25 @@ function printCrossModeHintAfterLocal(chain) {
2568
2576
  async function runConnectFlow(program2, opts) {
2569
2577
  const force = Boolean(opts.force);
2570
2578
  const importPath = opts.import;
2571
- let mode2;
2579
+ let mode;
2572
2580
  if (opts.mode === "session" || opts.mode === "local") {
2573
- mode2 = opts.mode;
2581
+ mode = opts.mode;
2574
2582
  } else if (opts.mode !== void 0) {
2575
2583
  throw errInvalidArgs("`--mode` must be 'session' or 'local'.");
2576
2584
  }
2577
2585
  if (opts.instanceName !== void 0) {
2578
- if (mode2 === "local") {
2586
+ if (mode === "local") {
2579
2587
  throw errInvalidArgs("`--instance-name` is only valid with `--mode session`.");
2580
2588
  }
2581
- mode2 = "session";
2589
+ mode = "session";
2582
2590
  }
2583
2591
  if (importPath) {
2584
- if (mode2 === "session") {
2592
+ if (mode === "session") {
2585
2593
  throw errInvalidArgs("`--import` is only valid with `--mode local`.");
2586
2594
  }
2587
- mode2 = "local";
2595
+ mode = "local";
2588
2596
  }
2589
- if (!mode2) {
2597
+ if (!mode) {
2590
2598
  if (!isInteractiveAllowed(program2)) {
2591
2599
  throw errInvalidArgs(
2592
2600
  "Specify `--mode <session|local>` in non-interactive mode."
@@ -2602,9 +2610,9 @@ async function runConnectFlow(program2, opts) {
2602
2610
  cancelMessage: "Wallet connect cancelled."
2603
2611
  });
2604
2612
  if (choice === null) throw new WalletConnectInterruptedError();
2605
- mode2 = choice;
2613
+ mode = choice;
2606
2614
  }
2607
- if (mode2 === "session") {
2615
+ if (mode === "session") {
2608
2616
  await runSessionConnect({
2609
2617
  program: program2,
2610
2618
  force,
@@ -3097,15 +3105,15 @@ async function requestJSON(url, options) {
3097
3105
  async function callApiData(apiKey, path, options = {}) {
3098
3106
  if (!apiKey) throw errAuthRequired();
3099
3107
  const override = parseBaseURLOverride(DATA_API_BASE_URL_ENV);
3100
- const base2 = override ? new URL(`/data/v1/${apiKey}/`, override) : new URL(`https://api.g.${getBaseDomain()}/data/v1/${apiKey}/`);
3101
- const url = withQuery(new URL(path.replace(/^\//, ""), base2), options.query);
3108
+ const base = override ? new URL(`/data/v1/${apiKey}/`, override) : new URL(`https://api.g.${getBaseDomain()}/data/v1/${apiKey}/`);
3109
+ const url = withQuery(new URL(path.replace(/^\//, ""), base), options.query);
3102
3110
  return requestJSON(url, { ...options, path });
3103
3111
  }
3104
3112
  async function callApiPrices(apiKey, path, options = {}) {
3105
3113
  if (!apiKey) throw errAuthRequired();
3106
3114
  const override = parseBaseURLOverride(PRICES_API_BASE_URL_ENV);
3107
- const base2 = override ? new URL(`/prices/v1/${apiKey}/`, override) : new URL(`https://api.g.${getBaseDomain()}/prices/v1/${apiKey}/`);
3108
- const url = withQuery(new URL(path.replace(/^\//, ""), base2), options.query);
3115
+ const base = override ? new URL(`/prices/v1/${apiKey}/`, override) : new URL(`https://api.g.${getBaseDomain()}/prices/v1/${apiKey}/`);
3116
+ const url = withQuery(new URL(path.replace(/^\//, ""), base), options.query);
3109
3117
  return requestJSON(url, { ...options, path });
3110
3118
  }
3111
3119
  async function callNotify(token, path, options = {}) {
@@ -3114,8 +3122,8 @@ async function callNotify(token, path, options = {}) {
3114
3122
  "Webhook API key required. Set ALCHEMY_WEBHOOK_API_KEY (or ALCHEMY_NOTIFY_AUTH_TOKEN) or pass --webhook-api-key."
3115
3123
  );
3116
3124
  }
3117
- const base2 = new URL(`https://dashboard.${getBaseDomain()}/api/`);
3118
- const url = withQuery(new URL(path.replace(/^\//, ""), base2), options.query);
3125
+ const base = new URL(`https://dashboard.${getBaseDomain()}/api/`);
3126
+ const url = withQuery(new URL(path.replace(/^\//, ""), base), options.query);
3119
3127
  return requestJSON(url, {
3120
3128
  ...options,
3121
3129
  path,
@@ -4267,51 +4275,10 @@ import { createSmartWalletClient } from "@alchemy/wallet-apis";
4267
4275
  import { privateKeyToAccount as privateKeyToAccount2 } from "viem/accounts";
4268
4276
 
4269
4277
  // src/lib/chains.ts
4270
- import * as viemChains from "viem/chains";
4271
- var NETWORK_TO_CHAIN = {
4272
- "eth-mainnet": viemChains.mainnet,
4273
- "eth-sepolia": viemChains.sepolia,
4274
- "eth-holesky": viemChains.holesky,
4275
- "base-mainnet": viemChains.base,
4276
- "base-sepolia": viemChains.baseSepolia,
4277
- "arb-mainnet": viemChains.arbitrum,
4278
- "arb-sepolia": viemChains.arbitrumSepolia,
4279
- "opt-mainnet": viemChains.optimism,
4280
- "opt-sepolia": viemChains.optimismSepolia,
4281
- "polygon-mainnet": viemChains.polygon,
4282
- "polygon-amoy": viemChains.polygonAmoy,
4283
- "zksync-mainnet": viemChains.zksync,
4284
- "zksync-sepolia": viemChains.zksyncSepoliaTestnet,
4285
- "avax-mainnet": viemChains.avalanche,
4286
- "avax-fuji": viemChains.avalancheFuji,
4287
- "bnb-mainnet": viemChains.bsc,
4288
- "bnb-testnet": viemChains.bscTestnet,
4289
- "linea-mainnet": viemChains.linea,
4290
- "linea-sepolia": viemChains.lineaSepolia,
4291
- "scroll-mainnet": viemChains.scroll,
4292
- "scroll-sepolia": viemChains.scrollSepolia,
4293
- "blast-mainnet": viemChains.blast,
4294
- "blast-sepolia": viemChains.blastSepolia,
4295
- "zora-mainnet": viemChains.zora,
4296
- "zora-sepolia": viemChains.zoraSepolia,
4297
- "celo-mainnet": viemChains.celo,
4298
- "gnosis-mainnet": viemChains.gnosis,
4299
- "mantle-mainnet": viemChains.mantle,
4300
- "worldchain-mainnet": viemChains.worldchain,
4301
- "shape-mainnet": viemChains.shape,
4302
- "unichain-mainnet": viemChains.unichain,
4303
- "unichain-sepolia": viemChains.unichainSepolia,
4304
- "ink-mainnet": viemChains.ink,
4305
- "ink-sepolia": viemChains.inkSepolia,
4306
- "soneium-mainnet": viemChains.soneium,
4307
- "frax-mainnet": viemChains.fraxtal,
4308
- "mode-mainnet": viemChains.mode,
4309
- "berachain-mainnet": viemChains.berachain
4310
- };
4311
4278
  function networkToChain(network) {
4312
- const chain = NETWORK_TO_CHAIN[network];
4279
+ const chain = walletNetworkToChain(network);
4313
4280
  if (!chain) {
4314
- const supported = Object.keys(NETWORK_TO_CHAIN).sort().join(", ");
4281
+ const supported = supportedWalletNetworks().join(", ");
4315
4282
  throw errInvalidArgs(
4316
4283
  `Network "${network}" is not supported for wallet operations. Supported networks: ${supported}`
4317
4284
  );
@@ -5102,6 +5069,517 @@ function formatError(error) {
5102
5069
  }
5103
5070
  }
5104
5071
 
5072
+ // ../../packages/sdk/dist/data/index.js
5073
+ var DEFAULT_DATA_TIMEOUT_MS = 3e4;
5074
+ var DEFAULT_BREADCRUMB_HEADER = "alchemy-sdk";
5075
+ var DataApiError = class extends Error {
5076
+ status;
5077
+ constructor(status, message) {
5078
+ super(message);
5079
+ this.status = status;
5080
+ this.name = "DataApiError";
5081
+ }
5082
+ };
5083
+ async function dataGet(baseUrl, apiKey, path, params, options = {}) {
5084
+ const url = new URL(`${baseUrl}/${apiKey}${path}`);
5085
+ if (params) {
5086
+ for (const [key, value] of Object.entries(params)) {
5087
+ if (value === void 0)
5088
+ continue;
5089
+ if (Array.isArray(value)) {
5090
+ for (const item of value)
5091
+ url.searchParams.append(key, item);
5092
+ } else {
5093
+ url.searchParams.set(key, value);
5094
+ }
5095
+ }
5096
+ }
5097
+ const resp = await dataFetch(url.toString(), "GET", void 0, options);
5098
+ return resp.json();
5099
+ }
5100
+ async function dataPost(baseUrl, apiKey, path, body, options = {}) {
5101
+ const resp = await dataFetch(`${baseUrl}/${apiKey}${path}`, "POST", body, options);
5102
+ return resp.json();
5103
+ }
5104
+ function nftBaseUrl(network, options = {}) {
5105
+ validateNetwork(network);
5106
+ return `https://${network}.${getGatewayDomain(options)}/nft/v3`;
5107
+ }
5108
+ function pricesBaseUrl(options = {}) {
5109
+ return `https://api.${getGatewayDomain(options)}/prices/v1`;
5110
+ }
5111
+ function portfolioBaseUrl(options = {}) {
5112
+ return `https://api.${getGatewayDomain(options)}/data/v1`;
5113
+ }
5114
+ function createAlchemyDataClient(apiKey, options = {}) {
5115
+ return new AlchemyDataClient(apiKey, options);
5116
+ }
5117
+ var AlchemyDataClient = class {
5118
+ apiKey;
5119
+ options;
5120
+ nft;
5121
+ prices;
5122
+ portfolio;
5123
+ constructor(apiKey, options = {}) {
5124
+ this.apiKey = apiKey;
5125
+ this.options = options;
5126
+ this.nft = new NftApiClient(apiKey, options);
5127
+ this.prices = new PricesApiClient(apiKey, options);
5128
+ this.portfolio = new PortfolioApiClient(apiKey, options);
5129
+ }
5130
+ };
5131
+ var NftApiClient = class {
5132
+ apiKey;
5133
+ options;
5134
+ constructor(apiKey, options = {}) {
5135
+ this.apiKey = apiKey;
5136
+ this.options = options;
5137
+ }
5138
+ getNFTsForOwner(network, params) {
5139
+ return this.get(network, "/getNFTsForOwner", params);
5140
+ }
5141
+ getNFTsForContract(network, params) {
5142
+ return this.get(network, "/getNFTsForContract", params);
5143
+ }
5144
+ getNFTMetadata(network, params) {
5145
+ return this.get(network, "/getNFTMetadata", params);
5146
+ }
5147
+ getNFTMetadataBatch(network, body) {
5148
+ return this.post(network, "/getNFTMetadataBatch", body);
5149
+ }
5150
+ getContractMetadata(network, params) {
5151
+ return this.get(network, "/getContractMetadata", params);
5152
+ }
5153
+ getOwnersForNFT(network, params) {
5154
+ return this.get(network, "/getOwnersForNFT", params);
5155
+ }
5156
+ getOwnersForContract(network, params) {
5157
+ return this.get(network, "/getOwnersForContract", params);
5158
+ }
5159
+ getFloorPrice(network, params) {
5160
+ return this.get(network, "/getFloorPrice", params);
5161
+ }
5162
+ isSpamContract(network, params) {
5163
+ return this.get(network, "/isSpamContract", params);
5164
+ }
5165
+ searchContractMetadata(network, params) {
5166
+ return this.get(network, "/searchContractMetadata", params);
5167
+ }
5168
+ getNFTSales(network, params) {
5169
+ return this.get(network, "/getNFTSales", params);
5170
+ }
5171
+ getContractsForOwner(network, params) {
5172
+ return this.get(network, "/getContractsForOwner", params);
5173
+ }
5174
+ getNFTsForCollection(network, params) {
5175
+ return this.get(network, "/getNFTsForCollection", params);
5176
+ }
5177
+ getCollectionMetadata(network, params) {
5178
+ return this.get(network, "/getCollectionMetadata", params);
5179
+ }
5180
+ getContractMetadataBatch(network, body) {
5181
+ return this.post(network, "/getContractMetadataBatch", body);
5182
+ }
5183
+ getSpamContracts(network) {
5184
+ return this.get(network, "/getSpamContracts", {});
5185
+ }
5186
+ isAirdropNFT(network, params) {
5187
+ return this.get(network, "/isAirdropNFT", params);
5188
+ }
5189
+ summarizeNFTAttributes(network, params) {
5190
+ return this.get(network, "/summarizeNFTAttributes", params);
5191
+ }
5192
+ isHolderOfContract(network, params) {
5193
+ return this.get(network, "/isHolderOfContract", params);
5194
+ }
5195
+ computeRarity(network, params) {
5196
+ return this.get(network, "/computeRarity", params);
5197
+ }
5198
+ getCollectionsForOwner(network, params) {
5199
+ return this.get(network, "/getCollectionsForOwner", params);
5200
+ }
5201
+ get(network, path, params) {
5202
+ return dataGet(nftBaseUrl(network, this.options), this.apiKey, path, params, this.options);
5203
+ }
5204
+ post(network, path, body) {
5205
+ return dataPost(nftBaseUrl(network, this.options), this.apiKey, path, body, this.options);
5206
+ }
5207
+ };
5208
+ var PricesApiClient = class {
5209
+ apiKey;
5210
+ options;
5211
+ constructor(apiKey, options = {}) {
5212
+ this.apiKey = apiKey;
5213
+ this.options = options;
5214
+ }
5215
+ getTokenPricesBySymbol(params) {
5216
+ return dataGet(pricesBaseUrl(this.options), this.apiKey, "/tokens/by-symbol", params, this.options);
5217
+ }
5218
+ getTokenPricesByAddress(body) {
5219
+ return dataPost(pricesBaseUrl(this.options), this.apiKey, "/tokens/by-address", body, this.options);
5220
+ }
5221
+ getHistoricalTokenPrices(body) {
5222
+ return dataPost(pricesBaseUrl(this.options), this.apiKey, "/tokens/historical", body, this.options);
5223
+ }
5224
+ };
5225
+ var PortfolioApiClient = class {
5226
+ apiKey;
5227
+ options;
5228
+ constructor(apiKey, options = {}) {
5229
+ this.apiKey = apiKey;
5230
+ this.options = options;
5231
+ }
5232
+ getTokensByAddress(body) {
5233
+ return this.post("/assets/tokens/by-address", body);
5234
+ }
5235
+ getTokenBalancesByAddress(body) {
5236
+ return this.post("/assets/tokens/balances/by-address", body);
5237
+ }
5238
+ getNFTsByAddress(body) {
5239
+ return this.post("/assets/nfts/by-address", body);
5240
+ }
5241
+ getNFTContractsByAddress(body) {
5242
+ return this.post("/assets/nfts/contracts/by-address", body);
5243
+ }
5244
+ post(path, body) {
5245
+ return dataPost(portfolioBaseUrl(this.options), this.apiKey, path, body, this.options);
5246
+ }
5247
+ };
5248
+ async function dataFetch(url, method, body, options) {
5249
+ const fetchFn = options.fetchFn ?? fetch;
5250
+ const resp = await fetchFn(url, {
5251
+ method,
5252
+ headers: {
5253
+ ...body !== void 0 && { "Content-Type": "application/json" },
5254
+ Accept: "application/json",
5255
+ "x-alchemy-client-breadcrumb": options.breadcrumb ?? DEFAULT_BREADCRUMB_HEADER
5256
+ },
5257
+ ...body !== void 0 && { body: JSON.stringify(body) },
5258
+ signal: AbortSignal.timeout(options.timeoutMs ?? DEFAULT_DATA_TIMEOUT_MS)
5259
+ });
5260
+ if (!resp.ok) {
5261
+ const text = await resp.text().catch(() => "");
5262
+ throw new DataApiError(resp.status, text || `HTTP ${resp.status}`);
5263
+ }
5264
+ return resp;
5265
+ }
5266
+
5267
+ // ../../packages/sdk/dist/surfaces/index.js
5268
+ var RPC_API_SURFACE = [
5269
+ { name: "ethGetBalance", rpcMethod: "eth_getBalance", family: "evm", gateway: "network" },
5270
+ { name: "ethGetBlockByNumber", rpcMethod: "eth_getBlockByNumber", family: "evm", gateway: "network" },
5271
+ { name: "ethGetBlockByHash", rpcMethod: "eth_getBlockByHash", family: "evm", gateway: "network" },
5272
+ { name: "ethGetTransactionByHash", rpcMethod: "eth_getTransactionByHash", family: "evm", gateway: "network" },
5273
+ { name: "ethGetTransactionReceipt", rpcMethod: "eth_getTransactionReceipt", family: "evm", gateway: "network" },
5274
+ { name: "ethGetTransactionCount", rpcMethod: "eth_getTransactionCount", family: "evm", gateway: "network" },
5275
+ { name: "ethBlockNumber", rpcMethod: "eth_blockNumber", family: "evm", gateway: "network" },
5276
+ { name: "ethGasPrice", rpcMethod: "eth_gasPrice", family: "evm", gateway: "network" },
5277
+ { name: "ethEstimateGas", rpcMethod: "eth_estimateGas", family: "evm", gateway: "network" },
5278
+ { name: "ethGetCode", rpcMethod: "eth_getCode", family: "evm", gateway: "network" },
5279
+ { name: "ethGetStorageAt", rpcMethod: "eth_getStorageAt", family: "evm", gateway: "network" },
5280
+ { name: "ethGetLogs", rpcMethod: "eth_getLogs", family: "evm", gateway: "network" },
5281
+ { name: "ethChainId", rpcMethod: "eth_chainId", family: "evm", gateway: "network" },
5282
+ { name: "ethFeeHistory", rpcMethod: "eth_feeHistory", family: "evm", gateway: "network" },
5283
+ { name: "ethMaxPriorityFeePerGas", rpcMethod: "eth_maxPriorityFeePerGas", family: "evm", gateway: "network" },
5284
+ { name: "netVersion", rpcMethod: "net_version", family: "evm", gateway: "network" },
5285
+ { name: "web3ClientVersion", rpcMethod: "web3_clientVersion", family: "evm", gateway: "network" },
5286
+ { name: "ethGetBlockTransactionCountByHash", rpcMethod: "eth_getBlockTransactionCountByHash", family: "evm", gateway: "network" },
5287
+ { name: "ethGetBlockTransactionCountByNumber", rpcMethod: "eth_getBlockTransactionCountByNumber", family: "evm", gateway: "network" },
5288
+ { name: "ethGetTransactionByBlockHashAndIndex", rpcMethod: "eth_getTransactionByBlockHashAndIndex", family: "evm", gateway: "network" },
5289
+ { name: "ethGetTransactionByBlockNumberAndIndex", rpcMethod: "eth_getTransactionByBlockNumberAndIndex", family: "evm", gateway: "network" },
5290
+ { name: "ethSyncing", rpcMethod: "eth_syncing", family: "evm", gateway: "network" },
5291
+ { name: "ethCallBundle", rpcMethod: "eth_callBundle", family: "evm", gateway: "network" },
5292
+ { name: "ethCallMany", rpcMethod: "eth_callMany", family: "evm", gateway: "network" },
5293
+ { name: "netListening", rpcMethod: "net_listening", family: "evm", gateway: "network" },
5294
+ { name: "web3Sha3", rpcMethod: "web3_sha3", family: "evm", gateway: "network" },
5295
+ { name: "getTokenBalances", rpcMethod: "alchemy_getTokenBalances", family: "evm", gateway: "network" },
5296
+ { name: "getTokenMetadata", rpcMethod: "alchemy_getTokenMetadata", family: "evm", gateway: "network" },
5297
+ { name: "getTokenAllowance", rpcMethod: "alchemy_getTokenAllowance", family: "evm", gateway: "network" },
5298
+ { name: "getAssetTransfers", rpcMethod: "alchemy_getAssetTransfers", family: "evm", gateway: "network" },
5299
+ { name: "getTransactionReceipts", rpcMethod: "alchemy_getTransactionReceipts", family: "evm", gateway: "network" },
5300
+ { name: "simulateAssetChanges", rpcMethod: "alchemy_simulateAssetChanges", family: "evm", gateway: "network" },
5301
+ { name: "simulateExecution", rpcMethod: "alchemy_simulateExecution", family: "evm", gateway: "network" },
5302
+ { name: "traceCall", rpcMethod: "trace_call", family: "evm", gateway: "network" },
5303
+ { name: "traceTransaction", rpcMethod: "trace_transaction", family: "evm", gateway: "network" },
5304
+ { name: "traceBlock", rpcMethod: "trace_block", family: "evm", gateway: "network" },
5305
+ { name: "debugTraceTransaction", rpcMethod: "debug_traceTransaction", family: "evm", gateway: "network" },
5306
+ { name: "debugTraceCall", rpcMethod: "debug_traceCall", family: "evm", gateway: "network" },
5307
+ { name: "estimateUserOperationGas", rpcMethod: "estimateUserOperationGas", family: "evm", gateway: "network" },
5308
+ { name: "getUserOperationReceipt", rpcMethod: "getUserOperationReceipt", family: "evm", gateway: "network" },
5309
+ { name: "getUserOperationByHash", rpcMethod: "getUserOperationByHash", family: "evm", gateway: "network" },
5310
+ { name: "supportedEntryPoints", rpcMethod: "supportedEntryPoints", family: "evm", gateway: "network" },
5311
+ { name: "solana_getAsset", rpcMethod: "getAsset", family: "solana", gateway: "network" },
5312
+ { name: "solana_getAssetsByOwner", rpcMethod: "getAssetsByOwner", family: "solana", gateway: "network" },
5313
+ { name: "solana_searchAssets", rpcMethod: "searchAssets", family: "solana", gateway: "network" },
5314
+ { name: "getTokenAccounts", rpcMethod: "getTokenAccounts", family: "solana", gateway: "network" },
5315
+ { name: "solana_getAssets", rpcMethod: "getAssets", family: "solana", gateway: "network" },
5316
+ { name: "solana_getAssetProof", rpcMethod: "getAssetProof", family: "solana", gateway: "network" },
5317
+ { name: "solana_getAssetsByAuthority", rpcMethod: "getAssetsByAuthority", family: "solana", gateway: "network" },
5318
+ { name: "solana_getAssetsByGroup", rpcMethod: "getAssetsByGroup", family: "solana", gateway: "network" },
5319
+ { name: "solana_getAssetsByCreator", rpcMethod: "getAssetsByCreator", family: "solana", gateway: "network" },
5320
+ { name: "solana_getAssetSignatures", rpcMethod: "getAssetSignatures", family: "solana", gateway: "network" },
5321
+ { name: "getNftEditions", rpcMethod: "getNftEditions", family: "solana", gateway: "network" },
5322
+ { name: "simulateAssetChangesBundle", rpcMethod: "alchemy_simulateAssetChangesBundle", family: "evm", gateway: "network" },
5323
+ { name: "simulateExecutionBundle", rpcMethod: "alchemy_simulateExecutionBundle", family: "evm", gateway: "network" },
5324
+ { name: "simulateUserOperationAssetChanges", rpcMethod: "alchemy_simulateUserOperationAssetChanges", family: "evm", gateway: "network" },
5325
+ { name: "traceFilter", rpcMethod: "trace_filter", family: "evm", gateway: "network" },
5326
+ { name: "traceReplayTransaction", rpcMethod: "trace_replayTransaction", family: "evm", gateway: "network" },
5327
+ { name: "traceReplayBlockTransactions", rpcMethod: "trace_replayBlockTransactions", family: "evm", gateway: "network" },
5328
+ { name: "debugTraceBlockByNumber", rpcMethod: "debug_traceBlockByNumber", family: "evm", gateway: "network" },
5329
+ { name: "debugTraceBlockByHash", rpcMethod: "debug_traceBlockByHash", family: "evm", gateway: "network" },
5330
+ { name: "debugGetRawBlock", rpcMethod: "debug_getRawBlock", family: "evm", gateway: "network" },
5331
+ { name: "debugGetRawReceipts", rpcMethod: "debug_getRawReceipts", family: "evm", gateway: "network" },
5332
+ { name: "requestGasAndPaymasterAndData", rpcMethod: "alchemy_requestGasAndPaymasterAndData", family: "evm", gateway: "network" },
5333
+ { name: "requestPaymasterAndData", rpcMethod: "alchemy_requestPaymasterAndData", family: "evm", gateway: "network" },
5334
+ { name: "ethCall", rpcMethod: "eth_call", family: "evm", gateway: "network" },
5335
+ { name: "ethGetBlockReceipts", rpcMethod: "eth_getBlockReceipts", family: "evm", gateway: "network" },
5336
+ { name: "ethGetProof", rpcMethod: "eth_getProof", family: "evm", gateway: "network" },
5337
+ { name: "ethCreateAccessList", rpcMethod: "eth_createAccessList", family: "evm", gateway: "network" },
5338
+ { name: "ethBlobBaseFee", rpcMethod: "eth_blobBaseFee", family: "evm", gateway: "network" },
5339
+ { name: "rundlerMaxPriorityFeePerGas", rpcMethod: "rundler_maxPriorityFeePerGas", family: "evm", gateway: "network" },
5340
+ { name: "solana_getBalance", rpcMethod: "getBalance", family: "solana", gateway: "network" },
5341
+ { name: "solana_getAccountInfo", rpcMethod: "getAccountInfo", family: "solana", gateway: "network" },
5342
+ { name: "solana_getMultipleAccounts", rpcMethod: "getMultipleAccounts", family: "solana", gateway: "network" },
5343
+ { name: "solana_getTransaction", rpcMethod: "getTransaction", family: "solana", gateway: "network" },
5344
+ { name: "solana_getSignaturesForAddress", rpcMethod: "getSignaturesForAddress", family: "solana", gateway: "network" },
5345
+ { name: "solana_getSignatureStatuses", rpcMethod: "getSignatureStatuses", family: "solana", gateway: "network" },
5346
+ { name: "solana_simulateTransaction", rpcMethod: "simulateTransaction", family: "solana", gateway: "network" },
5347
+ { name: "solana_getTokenAccountBalance", rpcMethod: "getTokenAccountBalance", family: "solana", gateway: "network" },
5348
+ { name: "solana_getTokenAccountsByOwner", rpcMethod: "getTokenAccountsByOwner", family: "solana", gateway: "network" },
5349
+ { name: "solana_getTokenAccountsByDelegate", rpcMethod: "getTokenAccountsByDelegate", family: "solana", gateway: "network" },
5350
+ { name: "solana_getTokenSupply", rpcMethod: "getTokenSupply", family: "solana", gateway: "network" },
5351
+ { name: "solana_getTokenLargestAccounts", rpcMethod: "getTokenLargestAccounts", family: "solana", gateway: "network" },
5352
+ { name: "solana_getBlock", rpcMethod: "getBlock", family: "solana", gateway: "network" },
5353
+ { name: "solana_getBlockHeight", rpcMethod: "getBlockHeight", family: "solana", gateway: "network" },
5354
+ { name: "solana_getBlockTime", rpcMethod: "getBlockTime", family: "solana", gateway: "network" },
5355
+ { name: "solana_getBlocks", rpcMethod: "getBlocks", family: "solana", gateway: "network" },
5356
+ { name: "solana_getSlot", rpcMethod: "getSlot", family: "solana", gateway: "network" },
5357
+ { name: "solana_getLatestBlockhash", rpcMethod: "getLatestBlockhash", family: "solana", gateway: "network" },
5358
+ { name: "solana_isBlockhashValid", rpcMethod: "isBlockhashValid", family: "solana", gateway: "network" },
5359
+ { name: "solana_getProgramAccounts", rpcMethod: "getProgramAccounts", family: "solana", gateway: "network" },
5360
+ { name: "solana_getEpochInfo", rpcMethod: "getEpochInfo", family: "solana", gateway: "network" },
5361
+ { name: "solana_getSupply", rpcMethod: "getSupply", family: "solana", gateway: "network" },
5362
+ { name: "solana_getVersion", rpcMethod: "getVersion", family: "solana", gateway: "network" },
5363
+ { name: "solana_getTransactionCount", rpcMethod: "getTransactionCount", family: "solana", gateway: "network" },
5364
+ { name: "solana_getInflationRate", rpcMethod: "getInflationRate", family: "solana", gateway: "network" },
5365
+ { name: "solana_getInflationReward", rpcMethod: "getInflationReward", family: "solana", gateway: "network" },
5366
+ { name: "solana_getVoteAccounts", rpcMethod: "getVoteAccounts", family: "solana", gateway: "network" },
5367
+ { name: "solana_getLargestAccounts", rpcMethod: "getLargestAccounts", family: "solana", gateway: "network" },
5368
+ { name: "solana_getFeeForMessage", rpcMethod: "getFeeForMessage", family: "solana", gateway: "network" },
5369
+ { name: "solana_getRecentPrioritizationFees", rpcMethod: "getRecentPrioritizationFees", family: "solana", gateway: "network" },
5370
+ { name: "solana_getMinimumBalanceForRentExemption", rpcMethod: "getMinimumBalanceForRentExemption", family: "solana", gateway: "network" },
5371
+ { name: "solana_getPriorityFeeEstimate", rpcMethod: "getPriorityFeeEstimate", family: "solana", gateway: "network" },
5372
+ { name: "solana_getClusterNodes", rpcMethod: "getClusterNodes", family: "solana", gateway: "network" },
5373
+ { name: "solana_getLeaderSchedule", rpcMethod: "getLeaderSchedule", family: "solana", gateway: "network" },
5374
+ { name: "solana_getMaxRetransmitSlot", rpcMethod: "getMaxRetransmitSlot", family: "solana", gateway: "network" },
5375
+ { name: "solana_getMaxShredInsertSlot", rpcMethod: "getMaxShredInsertSlot", family: "solana", gateway: "network" },
5376
+ { name: "solana_getRecentPerformanceSamples", rpcMethod: "getRecentPerformanceSamples", family: "solana", gateway: "network" },
5377
+ { name: "solana_getFirstAvailableBlock", rpcMethod: "getFirstAvailableBlock", family: "solana", gateway: "network" },
5378
+ { name: "solana_getGenesisHash", rpcMethod: "getGenesisHash", family: "solana", gateway: "network" },
5379
+ { name: "solana_getHighestSnapshotSlot", rpcMethod: "getHighestSnapshotSlot", family: "solana", gateway: "network" },
5380
+ { name: "solana_getIdentity", rpcMethod: "getIdentity", family: "solana", gateway: "network" },
5381
+ { name: "solana_getInflationGovernor", rpcMethod: "getInflationGovernor", family: "solana", gateway: "network" },
5382
+ { name: "solana_minimumLedgerSlot", rpcMethod: "minimumLedgerSlot", family: "solana", gateway: "network" },
5383
+ { name: "solana_requestAirdrop", rpcMethod: "requestAirdrop", family: "solana", gateway: "network" },
5384
+ { name: "solana_getBlockCommitment", rpcMethod: "getBlockCommitment", family: "solana", gateway: "network" },
5385
+ { name: "solana_getBlockProduction", rpcMethod: "getBlockProduction", family: "solana", gateway: "network" },
5386
+ { name: "solana_getSlotLeader", rpcMethod: "getSlotLeader", family: "solana", gateway: "network" },
5387
+ { name: "solana_getSlotLeaders", rpcMethod: "getSlotLeaders", family: "solana", gateway: "network" },
5388
+ { name: "solana_getEpochSchedule", rpcMethod: "getEpochSchedule", family: "solana", gateway: "network" },
5389
+ { name: "solana_getBlocksWithLimit", rpcMethod: "getBlocksWithLimit", family: "solana", gateway: "network" },
5390
+ { name: "solana_getStakeActivation", rpcMethod: "getStakeActivation", family: "solana", gateway: "network" },
5391
+ { name: "solana_simulateBundle", rpcMethod: "simulateBundle", family: "solana", gateway: "network" }
5392
+ ];
5393
+ var DATA_API_SURFACE = [
5394
+ { name: "getNFTsForOwner", service: "nft", sdkMethod: "getNFTsForOwner", transport: "get", input: "query", requiresNetwork: true },
5395
+ { name: "getNFTsForContract", service: "nft", sdkMethod: "getNFTsForContract", transport: "get", input: "query", requiresNetwork: true },
5396
+ { name: "getNFTMetadata", service: "nft", sdkMethod: "getNFTMetadata", transport: "get", input: "query", requiresNetwork: true },
5397
+ { name: "getNFTMetadataBatch", service: "nft", sdkMethod: "getNFTMetadataBatch", transport: "post", input: "body", requiresNetwork: true },
5398
+ { name: "getContractMetadata", service: "nft", sdkMethod: "getContractMetadata", transport: "get", input: "query", requiresNetwork: true },
5399
+ { name: "getOwnersForNFT", service: "nft", sdkMethod: "getOwnersForNFT", transport: "get", input: "query", requiresNetwork: true },
5400
+ { name: "getOwnersForContract", service: "nft", sdkMethod: "getOwnersForContract", transport: "get", input: "query", requiresNetwork: true },
5401
+ { name: "getFloorPrice", service: "nft", sdkMethod: "getFloorPrice", transport: "get", input: "query", requiresNetwork: true },
5402
+ { name: "isSpamContract", service: "nft", sdkMethod: "isSpamContract", transport: "get", input: "query", requiresNetwork: true },
5403
+ { name: "searchContractMetadata", service: "nft", sdkMethod: "searchContractMetadata", transport: "get", input: "query", requiresNetwork: true },
5404
+ { name: "getNFTSales", service: "nft", sdkMethod: "getNFTSales", transport: "get", input: "query", requiresNetwork: true },
5405
+ { name: "getContractsForOwner", service: "nft", sdkMethod: "getContractsForOwner", transport: "get", input: "query", requiresNetwork: true },
5406
+ { name: "getNFTsForCollection", service: "nft", sdkMethod: "getNFTsForCollection", transport: "get", input: "query", requiresNetwork: true },
5407
+ { name: "getCollectionMetadata", service: "nft", sdkMethod: "getCollectionMetadata", transport: "get", input: "query", requiresNetwork: true },
5408
+ { name: "getContractMetadataBatch", service: "nft", sdkMethod: "getContractMetadataBatch", transport: "post", input: "body", requiresNetwork: true },
5409
+ { name: "getSpamContracts", service: "nft", sdkMethod: "getSpamContracts", transport: "get", input: "none", requiresNetwork: true },
5410
+ { name: "isAirdropNFT", service: "nft", sdkMethod: "isAirdropNFT", transport: "get", input: "query", requiresNetwork: true },
5411
+ { name: "summarizeNFTAttributes", service: "nft", sdkMethod: "summarizeNFTAttributes", transport: "get", input: "query", requiresNetwork: true },
5412
+ { name: "isHolderOfContract", service: "nft", sdkMethod: "isHolderOfContract", transport: "get", input: "query", requiresNetwork: true },
5413
+ { name: "computeRarity", service: "nft", sdkMethod: "computeRarity", transport: "get", input: "query", requiresNetwork: true },
5414
+ { name: "getCollectionsForOwner", service: "nft", sdkMethod: "getCollectionsForOwner", transport: "get", input: "query", requiresNetwork: true },
5415
+ { name: "getTokenPricesBySymbol", service: "prices", sdkMethod: "getTokenPricesBySymbol", transport: "get", input: "query", requiresNetwork: false },
5416
+ { name: "getTokenPricesByAddress", service: "prices", sdkMethod: "getTokenPricesByAddress", transport: "post", input: "body", requiresNetwork: false },
5417
+ { name: "getHistoricalTokenPrices", service: "prices", sdkMethod: "getHistoricalTokenPrices", transport: "post", input: "body", requiresNetwork: false },
5418
+ { name: "getTokensByAddress", service: "portfolio", sdkMethod: "getTokensByAddress", transport: "post", input: "body", requiresNetwork: false },
5419
+ { name: "getTokenBalancesByAddress", service: "portfolio", sdkMethod: "getTokenBalancesByAddress", transport: "post", input: "body", requiresNetwork: false },
5420
+ { name: "getNFTsByAddress", service: "portfolio", sdkMethod: "getNFTsByAddress", transport: "post", input: "body", requiresNetwork: false },
5421
+ { name: "getNFTContractsByAddress", service: "portfolio", sdkMethod: "getNFTContractsByAddress", transport: "post", input: "body", requiresNetwork: false }
5422
+ ];
5423
+ var RPC_API_TOOL_NAMES = RPC_API_SURFACE.map((method) => method.name);
5424
+ var DATA_API_TOOL_NAMES = DATA_API_SURFACE.map((method) => method.name);
5425
+
5426
+ // src/commands/surface-parity.ts
5427
+ function registerEvmRpcSurfaceCommands(root, rpc) {
5428
+ for (const method of RPC_API_SURFACE.filter((entry) => entry.family === "evm")) {
5429
+ registerRpcSurfaceCommand({ root, parent: rpc, method });
5430
+ }
5431
+ }
5432
+ function registerSolanaRpcSurfaceCommands(root, solana) {
5433
+ for (const method of RPC_API_SURFACE.filter((entry) => entry.family === "solana")) {
5434
+ registerRpcSurfaceCommand({ root, parent: solana, method });
5435
+ }
5436
+ }
5437
+ function registerDataSurfaceCommands(root, data) {
5438
+ for (const method of DATA_API_SURFACE) {
5439
+ const command = data.command(method.name).description(`Call ${method.name}`);
5440
+ if (method.input === "query") {
5441
+ command.option("--query <json>", "Query parameters as a JSON object", "{}");
5442
+ } else if (method.input === "body") {
5443
+ command.option("--body <json>", "Request body as a JSON object", "{}");
5444
+ }
5445
+ command.action(async (opts) => {
5446
+ try {
5447
+ const apiKey = resolveAPIKey(root);
5448
+ if (!apiKey) {
5449
+ throw errAuthRequired();
5450
+ }
5451
+ const client = createAlchemyDataClient(apiKey, { breadcrumb: "alchemy-cli" });
5452
+ const result = await withSpinner(
5453
+ `Calling ${method.name}...`,
5454
+ `Called ${method.name}`,
5455
+ () => callDataMethod(client, method, root, opts)
5456
+ );
5457
+ printSyntaxJSON(result);
5458
+ } catch (err) {
5459
+ exitWithError(mapDataError(err));
5460
+ }
5461
+ });
5462
+ }
5463
+ }
5464
+ function registerRpcSurfaceCommand({ root, parent, method }) {
5465
+ parent.command(method.name).description(`Call ${method.rpcMethod}`).option("--params <json>", "JSON-RPC params as an array or object", "[]").action(async (opts) => {
5466
+ try {
5467
+ const params = parseRpcParams(opts.params);
5468
+ let result;
5469
+ if (method.gateway === "global") {
5470
+ const apiKey = resolveAPIKey(root);
5471
+ if (!apiKey) {
5472
+ throw errAuthRequired();
5473
+ }
5474
+ if (!Array.isArray(params)) {
5475
+ throw errInvalidArgs("--params must be a JSON array for global RPC methods.");
5476
+ }
5477
+ result = await withSpinner(
5478
+ `Calling ${method.name}...`,
5479
+ `Called ${method.name}`,
5480
+ () => globalRpcCall(apiKey, method.rpcMethod, params, {
5481
+ breadcrumb: "alchemy-cli",
5482
+ ...timeout && { timeoutMs: timeout }
5483
+ })
5484
+ );
5485
+ } else {
5486
+ const client = method.family === "solana" ? clientFromFlags(root, { forceNetwork: resolveSolanaNetwork(root) }) : clientFromFlags(root);
5487
+ result = await withSpinner(
5488
+ `Calling ${method.name}...`,
5489
+ `Called ${method.name}`,
5490
+ () => client.call(method.rpcMethod, params)
5491
+ );
5492
+ }
5493
+ printSyntaxJSON(result);
5494
+ } catch (err) {
5495
+ exitWithError(mapRpcError(err));
5496
+ }
5497
+ });
5498
+ }
5499
+ function parseRpcParams(input) {
5500
+ const parsed = parseRequiredJSON(input, "--params");
5501
+ if (Array.isArray(parsed)) {
5502
+ return parsed;
5503
+ }
5504
+ if (isPlainObject(parsed)) {
5505
+ return parsed;
5506
+ }
5507
+ throw errInvalidArgs("--params must be a JSON array or object.");
5508
+ }
5509
+ async function callDataMethod(client, method, root, opts) {
5510
+ if (method.service === "nft") {
5511
+ const fn2 = client.nft[method.sdkMethod];
5512
+ const network = resolveNetwork(root);
5513
+ if (method.input === "none") {
5514
+ return await fn2.call(client.nft, network);
5515
+ }
5516
+ if (method.input === "body") {
5517
+ return await fn2.call(client.nft, network, parseDataObject(opts.body ?? "{}", "--body"));
5518
+ }
5519
+ return await fn2.call(client.nft, network, normalizeQuery(parseDataObject(opts.query ?? "{}", "--query")));
5520
+ }
5521
+ if (method.service === "prices") {
5522
+ const fn2 = client.prices[method.sdkMethod];
5523
+ if (method.input === "body") {
5524
+ return await fn2.call(client.prices, parseDataObject(opts.body ?? "{}", "--body"));
5525
+ }
5526
+ return await fn2.call(client.prices, parseDataObject(opts.query ?? "{}", "--query"));
5527
+ }
5528
+ const fn = client.portfolio[method.sdkMethod];
5529
+ return await fn.call(client.portfolio, parseDataObject(opts.body ?? "{}", "--body"));
5530
+ }
5531
+ function parseDataObject(input, label) {
5532
+ const parsed = parseRequiredJSON(input, label);
5533
+ if (isPlainObject(parsed)) {
5534
+ return parsed;
5535
+ }
5536
+ throw errInvalidArgs(`${label} must be a JSON object.`);
5537
+ }
5538
+ function normalizeQuery(input) {
5539
+ const out = {};
5540
+ for (const [key, value] of Object.entries(input)) {
5541
+ if (value === void 0 || value === null) {
5542
+ continue;
5543
+ }
5544
+ if (Array.isArray(value)) {
5545
+ out[key] = value.map((item) => String(item));
5546
+ } else {
5547
+ out[key] = String(value);
5548
+ }
5549
+ }
5550
+ return out;
5551
+ }
5552
+ function isPlainObject(value) {
5553
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
5554
+ }
5555
+ function mapRpcError(err) {
5556
+ if (!(err instanceof RpcApiError)) {
5557
+ return err;
5558
+ }
5559
+ if (err.status === 429) {
5560
+ return errRateLimited();
5561
+ }
5562
+ if (err.status === 401 || err.status === 403) {
5563
+ return errInvalidAPIKey(err.message);
5564
+ }
5565
+ if (err.status !== void 0) {
5566
+ return errNetwork(`HTTP ${err.status}: ${err.message}`);
5567
+ }
5568
+ return errRPC(err.code, err.message);
5569
+ }
5570
+ function mapDataError(err) {
5571
+ if (!(err instanceof DataApiError)) {
5572
+ return err;
5573
+ }
5574
+ if (err.status === 429) {
5575
+ return errRateLimited();
5576
+ }
5577
+ if (err.status === 401 || err.status === 403) {
5578
+ return errInvalidAPIKey(err.message);
5579
+ }
5580
+ return errNetwork(`HTTP ${err.status}: ${err.message}`);
5581
+ }
5582
+
5105
5583
  // src/commands/solana.ts
5106
5584
  function registerReservedSolanaCommand(args) {
5107
5585
  args.cmd.command(args.signature).description(args.description).action(() => {
@@ -5159,6 +5637,7 @@ function registerSolana(program2) {
5159
5637
  registerSolanaProgram(cmd);
5160
5638
  registerSolanaDelegate(cmd);
5161
5639
  registerStatus(cmd, { networkMode: "solana" });
5640
+ registerSolanaRpcSurfaceCommands(program2, cmd);
5162
5641
  registerReservedSolanaCommands(cmd);
5163
5642
  }
5164
5643
 
@@ -7110,6 +7589,7 @@ function registerData(program2) {
7110
7589
  registerTransfers(cmd);
7111
7590
  registerPrices(cmd);
7112
7591
  registerPortfolio(cmd);
7592
+ registerDataSurfaceCommands(program2, cmd);
7113
7593
  }
7114
7594
 
7115
7595
  // src/commands/debug.ts
@@ -7409,7 +7889,7 @@ Tip: use 'alchemy evm tx <hash>' for transaction details (value, block, nonce).
7409
7889
 
7410
7890
  // src/commands/rpc.ts
7411
7891
  function registerRPC(program2) {
7412
- program2.command("rpc").argument("<method>", "JSON-RPC method name (e.g. eth_blockNumber)").argument("[params...]", "Method parameters as JSON values").description("Make a raw JSON-RPC call").addHelpText(
7892
+ const cmd = program2.command("rpc").argument("<method>", "JSON-RPC method name (e.g. eth_blockNumber)").argument("[params...]", "Method parameters as JSON values").description("Make a raw JSON-RPC call").addHelpText(
7413
7893
  "after",
7414
7894
  `
7415
7895
  Examples:
@@ -7418,6 +7898,9 @@ Examples:
7418
7898
  alchemy evm rpc eth_getBlockByNumber "0x1" true`
7419
7899
  ).action(async (method, params) => {
7420
7900
  try {
7901
+ if (outputRpcHelp(cmd, method, params)) {
7902
+ return;
7903
+ }
7421
7904
  const client = clientFromFlags(program2);
7422
7905
  const parsed = params.map((p) => {
7423
7906
  try {
@@ -7437,6 +7920,24 @@ Examples:
7437
7920
  exitWithError(err);
7438
7921
  }
7439
7922
  });
7923
+ registerEvmRpcSurfaceCommands(program2, cmd);
7924
+ }
7925
+ function outputRpcHelp(cmd, method, params) {
7926
+ if (method !== "help") {
7927
+ return false;
7928
+ }
7929
+ const [topic] = params;
7930
+ if (!topic) {
7931
+ cmd.outputHelp();
7932
+ return true;
7933
+ }
7934
+ const subcommand = cmd.commands.find((command) => command.name() === topic);
7935
+ if (subcommand) {
7936
+ subcommand.outputHelp();
7937
+ return true;
7938
+ }
7939
+ cmd.outputHelp();
7940
+ return true;
7440
7941
  }
7441
7942
 
7442
7943
  // src/commands/send-evm.ts
@@ -7470,7 +7971,7 @@ Examples:
7470
7971
  dryRun: opts.dryRun
7471
7972
  });
7472
7973
  } catch (err) {
7473
- const { exitWithError: exitWithError2 } = await import("./errors-T6XE2I2L.js");
7974
+ const { exitWithError: exitWithError2 } = await import("./errors-YPNK3AVF.js");
7474
7975
  exitWithError2(err);
7475
7976
  }
7476
7977
  });
@@ -9387,7 +9888,7 @@ async function flushProcessOutput() {
9387
9888
  }
9388
9889
  program.name("alchemy").description(
9389
9890
  "The Alchemy CLI lets you query blockchain data, call JSON-RPC methods, and manage your Alchemy configuration."
9390
- ).version("0.9.2", "-v, --version", "display CLI version").option("--api-key <key>", "Alchemy API key (env: ALCHEMY_API_KEY)").option(
9891
+ ).version("0.9.3", "-v, --version", "display CLI version").option("--api-key <key>", "Alchemy API key (env: ALCHEMY_API_KEY)").option(
9391
9892
  "-n, --network <network>",
9392
9893
  "Target network (default: eth-mainnet) (env: ALCHEMY_NETWORK)"
9393
9894
  ).option("--x402", "Use x402 wallet-based gateway auth").option(
@@ -9574,11 +10075,11 @@ ${styledLine}`;
9574
10075
  "wallet"
9575
10076
  ];
9576
10077
  if (!skipAppPrompt.includes(cmdName) && isInteractiveAllowed(program) && !opts.apiKey && !process.env.ALCHEMY_API_KEY) {
9577
- const { resolveAuthToken: resolveAuthToken2 } = await import("./resolve-FQ66OWT7.js");
10078
+ const { resolveAuthToken: resolveAuthToken2 } = await import("./resolve-REZCFZZ7.js");
9578
10079
  const authToken = resolveAuthToken2(cfg);
9579
10080
  const hasApiKey = Boolean(cfg.api_key?.trim() || cfg.app?.apiKey);
9580
10081
  if (authToken && !hasApiKey) {
9581
- const { selectAppAfterAuth } = await import("./auth-6BBITIOZ.js");
10082
+ const { selectAppAfterAuth } = await import("./auth-23OYLRWN.js");
9582
10083
  console.log("");
9583
10084
  console.log(` No app selected. Please select an app to continue.`);
9584
10085
  await selectAppAfterAuth(authToken);
@@ -9613,7 +10114,7 @@ ${styledLine}`;
9613
10114
  if (isInteractiveAllowed(program)) {
9614
10115
  let latestForInteractiveStartup = null;
9615
10116
  if (shouldRunOnboarding(program, cfg)) {
9616
- const { runOnboarding } = await import("./onboarding-CW7XGRE4.js");
10117
+ const { runOnboarding } = await import("./onboarding-IJQ72DK7.js");
9617
10118
  const latest = getAvailableUpdateOnce();
9618
10119
  const completed = await runOnboarding(program, latest);
9619
10120
  updateShownDuringInteractiveStartup = Boolean(latest);
@@ -9627,7 +10128,7 @@ ${styledLine}`;
9627
10128
  latestForInteractiveStartup
9628
10129
  );
9629
10130
  }
9630
- const { startREPL } = await import("./interactive-IBR6RN74.js");
10131
+ const { startREPL } = await import("./interactive-KLVEYTQM.js");
9631
10132
  program.exitOverride();
9632
10133
  program.configureOutput({
9633
10134
  writeErr: () => {