@alchemy/cli 0.9.1 → 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-AJOLFTCZ.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
 
@@ -5593,7 +6072,108 @@ import {
5593
6072
  erc20Abi,
5594
6073
  maxUint256
5595
6074
  } from "viem";
6075
+
6076
+ // src/lib/token-registry.ts
5596
6077
  var NATIVE_TOKEN_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
6078
+ var REGISTRY = {
6079
+ "eth-mainnet": [
6080
+ { symbol: "ETH", address: NATIVE_TOKEN_ADDRESS, decimals: 18, name: "Ether", isNative: true },
6081
+ { symbol: "WETH", address: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", decimals: 18, name: "Wrapped Ether" },
6082
+ { symbol: "USDC", address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", decimals: 6, name: "USD Coin" },
6083
+ { symbol: "USDT", address: "0xdAC17F958D2ee523a2206206994597C13D831ec7", decimals: 6, name: "Tether USD" },
6084
+ { symbol: "DAI", address: "0x6B175474E89094C44Da98b954EedeAC495271d0F", decimals: 18, name: "Dai Stablecoin" },
6085
+ { symbol: "WBTC", address: "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", decimals: 8, name: "Wrapped BTC" }
6086
+ ],
6087
+ "base-mainnet": [
6088
+ { symbol: "ETH", address: NATIVE_TOKEN_ADDRESS, decimals: 18, name: "Ether", isNative: true },
6089
+ { symbol: "WETH", address: "0x4200000000000000000000000000000000000006", decimals: 18, name: "Wrapped Ether" },
6090
+ { symbol: "USDC", address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", decimals: 6, name: "USD Coin" },
6091
+ { symbol: "USDbC", address: "0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA", decimals: 6, name: "USD Base Coin (bridged)" },
6092
+ { symbol: "DAI", address: "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb", decimals: 18, name: "Dai Stablecoin" },
6093
+ { symbol: "cbETH", address: "0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22", decimals: 18, name: "Coinbase Wrapped Staked ETH" }
6094
+ ],
6095
+ "arb-mainnet": [
6096
+ { symbol: "ETH", address: NATIVE_TOKEN_ADDRESS, decimals: 18, name: "Ether", isNative: true },
6097
+ { symbol: "WETH", address: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", decimals: 18, name: "Wrapped Ether" },
6098
+ { symbol: "USDC", address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", decimals: 6, name: "USD Coin" },
6099
+ { symbol: "USDC.e", address: "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8", decimals: 6, name: "Bridged USD Coin (legacy)", aliases: ["USDCe"] },
6100
+ { symbol: "USDT", address: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9", decimals: 6, name: "Tether USD" },
6101
+ { symbol: "DAI", address: "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1", decimals: 18, name: "Dai Stablecoin" },
6102
+ { symbol: "WBTC", address: "0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f", decimals: 8, name: "Wrapped BTC" },
6103
+ { symbol: "ARB", address: "0x912CE59144191C1204E64559FE8253a0e49E6548", decimals: 18, name: "Arbitrum" }
6104
+ ],
6105
+ "opt-mainnet": [
6106
+ { symbol: "ETH", address: NATIVE_TOKEN_ADDRESS, decimals: 18, name: "Ether", isNative: true },
6107
+ { symbol: "WETH", address: "0x4200000000000000000000000000000000000006", decimals: 18, name: "Wrapped Ether" },
6108
+ { symbol: "USDC", address: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85", decimals: 6, name: "USD Coin" },
6109
+ { symbol: "USDC.e", address: "0x7F5c764cBc14f9669B88837ca1490cCa17c31607", decimals: 6, name: "Bridged USD Coin (legacy)", aliases: ["USDCe"] },
6110
+ { symbol: "USDT", address: "0x94b008aA00579c1307B0EF2c499aD98a8ce58e58", decimals: 6, name: "Tether USD" },
6111
+ { symbol: "DAI", address: "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1", decimals: 18, name: "Dai Stablecoin" },
6112
+ { symbol: "WBTC", address: "0x68f180fcCe6836688e9084f035309E29Bf0A2095", decimals: 8, name: "Wrapped BTC" },
6113
+ { symbol: "OP", address: "0x4200000000000000000000000000000000000042", decimals: 18, name: "Optimism" }
6114
+ ],
6115
+ "polygon-mainnet": [
6116
+ { symbol: "POL", address: NATIVE_TOKEN_ADDRESS, decimals: 18, name: "Polygon Ecosystem Token", isNative: true, aliases: ["MATIC"] },
6117
+ { symbol: "WPOL", address: "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270", decimals: 18, name: "Wrapped POL", aliases: ["WMATIC"] },
6118
+ { symbol: "USDC", address: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359", decimals: 6, name: "USD Coin" },
6119
+ { symbol: "USDC.e", address: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", decimals: 6, name: "Bridged USD Coin (legacy)", aliases: ["USDCe"] },
6120
+ { symbol: "USDT", address: "0xc2132D05D31c914a87C6611C10748AEb04B58e8F", decimals: 6, name: "Tether USD" },
6121
+ { symbol: "DAI", address: "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063", decimals: 18, name: "Dai Stablecoin" },
6122
+ { symbol: "WETH", address: "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619", decimals: 18, name: "Wrapped Ether" },
6123
+ { symbol: "WBTC", address: "0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6", decimals: 8, name: "Wrapped BTC" }
6124
+ ],
6125
+ "bnb-mainnet": [
6126
+ { symbol: "BNB", address: NATIVE_TOKEN_ADDRESS, decimals: 18, name: "BNB", isNative: true },
6127
+ { symbol: "WBNB", address: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", decimals: 18, name: "Wrapped BNB" },
6128
+ { symbol: "USDC", address: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d", decimals: 18, name: "Binance-Peg USD Coin" },
6129
+ { symbol: "USDT", address: "0x55d398326f99059fF775485246999027B3197955", decimals: 18, name: "Binance-Peg Tether USD" },
6130
+ { symbol: "DAI", address: "0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3", decimals: 18, name: "Binance-Peg Dai Token" },
6131
+ { symbol: "WETH", address: "0x2170Ed0880ac9A755fd29B2688956BD959F933F8", decimals: 18, name: "Binance-Peg Ether" },
6132
+ { symbol: "BTCB", address: "0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c", decimals: 18, name: "Binance-Peg BTC" }
6133
+ ],
6134
+ "avax-mainnet": [
6135
+ { symbol: "AVAX", address: NATIVE_TOKEN_ADDRESS, decimals: 18, name: "Avalanche", isNative: true },
6136
+ { symbol: "WAVAX", address: "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7", decimals: 18, name: "Wrapped AVAX" },
6137
+ { symbol: "USDC", address: "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E", decimals: 6, name: "USD Coin" },
6138
+ { symbol: "USDC.e", address: "0xA7D7079b0FEaD91F3e65f86E8915Cb59c1a4C664", decimals: 6, name: "Bridged USD Coin (legacy)", aliases: ["USDCe"] },
6139
+ { symbol: "USDT", address: "0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7", decimals: 6, name: "Tether USD" },
6140
+ { symbol: "USDT.e", address: "0xc7198437980c041c805A1EDcbA50c1Ce5db95118", decimals: 6, name: "Bridged Tether USD (legacy)", aliases: ["USDTe"] },
6141
+ { symbol: "DAI.e", address: "0xd586E7F844cEa2F87f50152665BCbc2C279D8d70", decimals: 18, name: "Bridged Dai Stablecoin" },
6142
+ { symbol: "WETH.e", address: "0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB", decimals: 18, name: "Bridged Wrapped Ether" }
6143
+ ]
6144
+ };
6145
+ function normalize(symbol) {
6146
+ return symbol.trim().toUpperCase();
6147
+ }
6148
+ var INDEX_CACHE = /* @__PURE__ */ new Map();
6149
+ function indexFor(network) {
6150
+ const cached = INDEX_CACHE.get(network);
6151
+ if (cached) return cached;
6152
+ const entries = REGISTRY[network] ?? [];
6153
+ const index = /* @__PURE__ */ new Map();
6154
+ for (const entry of entries) {
6155
+ index.set(normalize(entry.symbol), entry);
6156
+ for (const alias of entry.aliases ?? []) {
6157
+ index.set(normalize(alias), entry);
6158
+ }
6159
+ }
6160
+ INDEX_CACHE.set(network, index);
6161
+ return index;
6162
+ }
6163
+ function getRegistryNetworks() {
6164
+ return Object.keys(REGISTRY).sort();
6165
+ }
6166
+ function listRegistryTokens(network) {
6167
+ return REGISTRY[network] ?? [];
6168
+ }
6169
+ function findRegistryToken(network, symbol) {
6170
+ return indexFor(network).get(normalize(symbol)) ?? null;
6171
+ }
6172
+ function registrySymbolSuggestions(network) {
6173
+ return listRegistryTokens(network).map((t) => t.symbol);
6174
+ }
6175
+
6176
+ // src/commands/approve.ts
5597
6177
  function isNativeToken(address2) {
5598
6178
  return address2.toLowerCase() === NATIVE_TOKEN_ADDRESS.toLowerCase();
5599
6179
  }
@@ -7009,6 +7589,7 @@ function registerData(program2) {
7009
7589
  registerTransfers(cmd);
7010
7590
  registerPrices(cmd);
7011
7591
  registerPortfolio(cmd);
7592
+ registerDataSurfaceCommands(program2, cmd);
7012
7593
  }
7013
7594
 
7014
7595
  // src/commands/debug.ts
@@ -7308,7 +7889,7 @@ Tip: use 'alchemy evm tx <hash>' for transaction details (value, block, nonce).
7308
7889
 
7309
7890
  // src/commands/rpc.ts
7310
7891
  function registerRPC(program2) {
7311
- 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(
7312
7893
  "after",
7313
7894
  `
7314
7895
  Examples:
@@ -7317,6 +7898,9 @@ Examples:
7317
7898
  alchemy evm rpc eth_getBlockByNumber "0x1" true`
7318
7899
  ).action(async (method, params) => {
7319
7900
  try {
7901
+ if (outputRpcHelp(cmd, method, params)) {
7902
+ return;
7903
+ }
7320
7904
  const client = clientFromFlags(program2);
7321
7905
  const parsed = params.map((p) => {
7322
7906
  try {
@@ -7336,6 +7920,24 @@ Examples:
7336
7920
  exitWithError(err);
7337
7921
  }
7338
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;
7339
7941
  }
7340
7942
 
7341
7943
  // src/commands/send-evm.ts
@@ -7369,7 +7971,7 @@ Examples:
7369
7971
  dryRun: opts.dryRun
7370
7972
  });
7371
7973
  } catch (err) {
7372
- const { exitWithError: exitWithError2 } = await import("./errors-T6XE2I2L.js");
7974
+ const { exitWithError: exitWithError2 } = await import("./errors-YPNK3AVF.js");
7373
7975
  exitWithError2(err);
7374
7976
  }
7375
7977
  });
@@ -7638,10 +8240,9 @@ function normalizeQuoteError(err, flow) {
7638
8240
  }
7639
8241
 
7640
8242
  // src/commands/swap.ts
7641
- var NATIVE_TOKEN_ADDRESS2 = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
7642
8243
  var NATIVE_DECIMALS = 18;
7643
8244
  function isNativeToken2(address2) {
7644
- return address2.toLowerCase() === NATIVE_TOKEN_ADDRESS2.toLowerCase();
8245
+ return address2.toLowerCase() === NATIVE_TOKEN_ADDRESS.toLowerCase();
7645
8246
  }
7646
8247
  function slippagePercentToBasisPoints(percent) {
7647
8248
  return BigInt(Math.round(percent * 100));
@@ -7717,6 +8318,11 @@ function registerSwap(program2) {
7717
8318
  quoteCmd.addHelpText(
7718
8319
  "after",
7719
8320
  `
8321
+ Tip: use 'alchemy evm token <SYMBOL>' to resolve common token addresses
8322
+ (ETH, USDC, WETH, USDT, DAI, \u2026). Example:
8323
+ --from $(alchemy evm token ETH --address-only) \\
8324
+ --to $(alchemy evm token USDC --address-only -n eth-mainnet)
8325
+
7720
8326
  Examples:
7721
8327
  alchemy evm swap quote --from 0xEeee...EEeE --to 0xA0b8...USDC --amount 1.0 -n eth-mainnet
7722
8328
  alchemy evm swap quote --from 0xUSDC --to 0xDAI --amount 100 --slippage 1.0`
@@ -7732,6 +8338,10 @@ Examples:
7732
8338
  executeCmd.option("--gas-sponsored", "Enable gas sponsorship (env: ALCHEMY_EVM_GAS_SPONSORED)").option("--gas-policy-id <id>", "Gas policy ID for sponsorship (env: ALCHEMY_EVM_GAS_POLICY_ID)").addHelpText(
7733
8339
  "after",
7734
8340
  `
8341
+ Tip: use 'alchemy evm token <SYMBOL>' to resolve common token addresses
8342
+ (ETH, USDC, WETH, USDT, DAI, \u2026). Run 'alchemy evm token list' to discover
8343
+ known symbols on the current network.
8344
+
7735
8345
  Examples:
7736
8346
  alchemy evm swap execute --from 0xEeee...EEeE --to 0xA0b8...USDC --amount 1.0 -n eth-mainnet
7737
8347
  alchemy evm swap execute --from 0xUSDC --to 0xDAI --amount 100 --slippage 1.0
@@ -7894,6 +8504,153 @@ function extractQuoteData(quote) {
7894
8504
  return { type };
7895
8505
  }
7896
8506
 
8507
+ // src/commands/evm-token.ts
8508
+ function tokenJSON(token, network) {
8509
+ return {
8510
+ symbol: token.symbol,
8511
+ address: token.address,
8512
+ decimals: token.decimals,
8513
+ name: token.name,
8514
+ network,
8515
+ isNative: token.isNative === true,
8516
+ ...token.aliases?.length ? { aliases: token.aliases } : {}
8517
+ };
8518
+ }
8519
+ function registerEvmToken(program2) {
8520
+ const cmd = program2.command("token").description(
8521
+ "Look up known token addresses by symbol (ETH, USDC, WETH, etc.)"
8522
+ ).argument("[symbol]", "Token symbol (e.g. ETH, USDC, WETH)").option("--address-only", "Print only the resolved address (for scripting)").addHelpText(
8523
+ "after",
8524
+ `
8525
+ Symbols are matched case-insensitively. \`USDC\` resolves to the canonical
8526
+ Circle-issued token; \`USDC.e\` resolves to the legacy bridged variant where
8527
+ applicable. The native gas token (ETH, POL, BNB, AVAX, \u2026) resolves to the
8528
+ EIP-7528 native sentinel 0xEeee\u2026EEeE.
8529
+
8530
+ Examples:
8531
+ alchemy evm token ETH # uses current network
8532
+ alchemy evm token USDC -n base-mainnet
8533
+ alchemy evm token USDC.e -n arb-mainnet
8534
+ alchemy evm token USDC --address-only # prints just the 0x address
8535
+ alchemy --json evm token USDC | jq -r .address
8536
+
8537
+ alchemy evm token list # list tokens on current network
8538
+ alchemy evm token list --all # list tokens across all networks`
8539
+ ).action(async (symbol, opts) => {
8540
+ try {
8541
+ if (!symbol) {
8542
+ if (opts.addressOnly) {
8543
+ throw errInvalidArgs(
8544
+ "--address-only requires a symbol. Example: alchemy evm token USDC --address-only"
8545
+ );
8546
+ }
8547
+ await runList(program2, {});
8548
+ return;
8549
+ }
8550
+ await runLookup(program2, symbol, opts);
8551
+ } catch (err) {
8552
+ exitWithError(err);
8553
+ }
8554
+ });
8555
+ cmd.command("list").description("List known token symbols and addresses").option("--all", "List tokens across all supported networks").action(async (opts) => {
8556
+ try {
8557
+ await runList(program2, opts);
8558
+ } catch (err) {
8559
+ exitWithError(err);
8560
+ }
8561
+ });
8562
+ }
8563
+ async function runLookup(program2, symbol, opts) {
8564
+ const network = resolveNetwork(program2);
8565
+ const token = findRegistryToken(network, symbol);
8566
+ if (!token) {
8567
+ const supported = registrySymbolSuggestions(network);
8568
+ if (supported.length === 0) {
8569
+ throw errInvalidArgs(
8570
+ `No token registry entries for network ${network}. Run 'alchemy evm token list --all' to see supported networks, or pass the raw 0x address.`
8571
+ );
8572
+ }
8573
+ throw errNotFound(
8574
+ `token symbol "${symbol}" on ${network}. Known symbols: ${supported.join(", ")}.`
8575
+ );
8576
+ }
8577
+ if (opts.addressOnly) {
8578
+ console.log(token.address);
8579
+ return;
8580
+ }
8581
+ if (isJSONMode()) {
8582
+ printJSON(tokenJSON(token, network));
8583
+ return;
8584
+ }
8585
+ const pairs = [
8586
+ ["Symbol", green(token.symbol)],
8587
+ ["Name", token.name],
8588
+ ["Address", token.address],
8589
+ ["Decimals", String(token.decimals)],
8590
+ ["Network", network]
8591
+ ];
8592
+ if (token.isNative) pairs.push(["Native", "yes"]);
8593
+ if (token.aliases?.length) pairs.push(["Aliases", token.aliases.join(", ")]);
8594
+ printKeyValue(pairs);
8595
+ }
8596
+ async function runList(program2, opts) {
8597
+ if (opts.all) {
8598
+ const data = getRegistryNetworks().map((network2) => ({
8599
+ network: network2,
8600
+ tokens: listRegistryTokens(network2)
8601
+ }));
8602
+ if (isJSONMode()) {
8603
+ printJSON(
8604
+ data.map(({ network: network2, tokens: tokens2 }) => ({
8605
+ network: network2,
8606
+ tokens: tokens2.map((t) => tokenJSON(t, network2))
8607
+ }))
8608
+ );
8609
+ return;
8610
+ }
8611
+ for (let i = 0; i < data.length; i++) {
8612
+ const { network: network2, tokens: tokens2 } = data[i];
8613
+ if (i > 0) console.log("");
8614
+ console.log(` ${green(network2)} ${dim(`(${tokens2.length} tokens)`)}`);
8615
+ printTokenTable(tokens2);
8616
+ }
8617
+ console.log(
8618
+ `
8619
+ ${dim("Tip: pass -n/--network <net> to scope a lookup. Use 'alchemy evm token <SYMBOL>' to fetch a single address.")}`
8620
+ );
8621
+ return;
8622
+ }
8623
+ const network = resolveNetwork(program2);
8624
+ const tokens = listRegistryTokens(network);
8625
+ if (isJSONMode()) {
8626
+ printJSON({ network, tokens: tokens.map((t) => tokenJSON(t, network)) });
8627
+ return;
8628
+ }
8629
+ if (tokens.length === 0) {
8630
+ console.log(
8631
+ `
8632
+ ${dim(`No registry entries for ${network}. Supported networks: ${getRegistryNetworks().join(", ")}.`)}`
8633
+ );
8634
+ return;
8635
+ }
8636
+ console.log(` ${green(network)} ${dim(`(${tokens.length} tokens)`)}`);
8637
+ printTokenTable(tokens);
8638
+ console.log(
8639
+ `
8640
+ ${dim("Tip: 'alchemy evm token <SYMBOL>' resolves one symbol. Add --all to see every network.")}`
8641
+ );
8642
+ }
8643
+ function printTokenTable(tokens) {
8644
+ const rows = tokens.map((t) => [
8645
+ t.symbol,
8646
+ t.name,
8647
+ t.address,
8648
+ String(t.decimals),
8649
+ t.isNative ? "yes" : ""
8650
+ ]);
8651
+ printTable(["Symbol", "Name", "Address", "Decimals", "Native"], rows);
8652
+ }
8653
+
7897
8654
  // src/commands/trace.ts
7898
8655
  function normalizeTraceMethod(method) {
7899
8656
  if (method.startsWith("trace_")) return method;
@@ -7990,6 +8747,7 @@ function registerEvm(program2) {
7990
8747
  registerEvmSend(cmd);
7991
8748
  registerContract(cmd);
7992
8749
  registerSwap(cmd);
8750
+ registerEvmToken(cmd);
7993
8751
  registerApprove(cmd);
7994
8752
  registerStatus(cmd);
7995
8753
  registerNetwork(cmd);
@@ -8175,10 +8933,9 @@ function registerGasManager(program2) {
8175
8933
  import {
8176
8934
  swapActions as swapActions2
8177
8935
  } from "@alchemy/wallet-apis/experimental";
8178
- var NATIVE_TOKEN_ADDRESS3 = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
8179
8936
  var NATIVE_DECIMALS2 = 18;
8180
8937
  function isNativeToken3(address2) {
8181
- return address2.toLowerCase() === NATIVE_TOKEN_ADDRESS3.toLowerCase();
8938
+ return address2.toLowerCase() === NATIVE_TOKEN_ADDRESS.toLowerCase();
8182
8939
  }
8183
8940
  function slippagePercentToBasisPoints2(percent) {
8184
8941
  return BigInt(Math.round(percent * 100));
@@ -8269,7 +9026,7 @@ function extractQuoteData2(quote) {
8269
9026
  }
8270
9027
  function registerBridge(program2) {
8271
9028
  const cmd = program2.command("bridge").description("Bridge tokens from the source -n/--network to a destination --to-network");
8272
- const quoteCmd = cmd.command("quote").description("Get a bridge quote without executing").requiredOption("--from <token_address>", `Source token address (use ${NATIVE_TOKEN_ADDRESS3} for the native token)`).requiredOption("--to <token_address>", `Destination token address (use ${NATIVE_TOKEN_ADDRESS3} for the native token)`).requiredOption("--amount <number>", "Amount to bridge in decimal token units (for example, 1.5)").requiredOption("--to-network <network>", "Destination network (e.g. base-mainnet)").option("--from-address <address>", "Wallet/account address to quote from without changing signer selection").option("--slippage <percent>", "Max slippage percentage (omit to use the API default)");
9029
+ const quoteCmd = cmd.command("quote").description("Get a bridge quote without executing").requiredOption("--from <token_address>", `Source token address (use ${NATIVE_TOKEN_ADDRESS} for the native token)`).requiredOption("--to <token_address>", `Destination token address (use ${NATIVE_TOKEN_ADDRESS} for the native token)`).requiredOption("--amount <number>", "Amount to bridge in decimal token units (for example, 1.5)").requiredOption("--to-network <network>", "Destination network (e.g. base-mainnet)").option("--from-address <address>", "Wallet/account address to quote from without changing signer selection").option("--slippage <percent>", "Max slippage percentage (omit to use the API default)");
8273
9030
  addSignerOption(quoteCmd);
8274
9031
  quoteCmd.addHelpText(
8275
9032
  "after",
@@ -8277,8 +9034,11 @@ function registerBridge(program2) {
8277
9034
  Source network comes from the global -n/--network flag. Use --to-network for the destination chain.
8278
9035
  For same-chain token exchanges, use 'alchemy evm swap'.
8279
9036
 
9037
+ Tip: use 'alchemy evm token <SYMBOL>' to resolve common token addresses
9038
+ (ETH, USDC, WETH, USDT, DAI, \u2026) per chain.
9039
+
8280
9040
  Examples:
8281
- alchemy xchain bridge quote --from ${NATIVE_TOKEN_ADDRESS3} --to ${NATIVE_TOKEN_ADDRESS3} --amount 0.1 --to-network base-mainnet -n eth-mainnet
9041
+ alchemy xchain bridge quote --from ${NATIVE_TOKEN_ADDRESS} --to ${NATIVE_TOKEN_ADDRESS} --amount 0.1 --to-network base-mainnet -n eth-mainnet
8282
9042
  alchemy xchain bridge quote --from <eth_usdc_address> --to <arb_usdc_address> --amount 100 --to-network arb-mainnet -n eth-mainnet`
8283
9043
  ).action(async (opts) => {
8284
9044
  try {
@@ -8287,7 +9047,7 @@ Examples:
8287
9047
  exitWithError(err);
8288
9048
  }
8289
9049
  });
8290
- const executeCmd = cmd.command("execute").description("Execute a cross-chain bridge").requiredOption("--from <token_address>", `Source token address (use ${NATIVE_TOKEN_ADDRESS3} for the native token)`).requiredOption("--to <token_address>", `Destination token address (use ${NATIVE_TOKEN_ADDRESS3} for the native token)`).requiredOption("--amount <number>", "Amount to bridge in decimal token units (for example, 1.5)").requiredOption("--to-network <network>", "Destination network (e.g. base-mainnet)").option("--slippage <percent>", "Max slippage percentage (omit to use the API default)");
9050
+ const executeCmd = cmd.command("execute").description("Execute a cross-chain bridge").requiredOption("--from <token_address>", `Source token address (use ${NATIVE_TOKEN_ADDRESS} for the native token)`).requiredOption("--to <token_address>", `Destination token address (use ${NATIVE_TOKEN_ADDRESS} for the native token)`).requiredOption("--amount <number>", "Amount to bridge in decimal token units (for example, 1.5)").requiredOption("--to-network <network>", "Destination network (e.g. base-mainnet)").option("--slippage <percent>", "Max slippage percentage (omit to use the API default)");
8291
9051
  addSignerOption(executeCmd);
8292
9052
  executeCmd.option("--gas-sponsored", "Enable gas sponsorship (env: ALCHEMY_EVM_GAS_SPONSORED)").option("--gas-policy-id <id>", "Gas policy ID for sponsorship (env: ALCHEMY_EVM_GAS_POLICY_ID)").addHelpText(
8293
9053
  "after",
@@ -8295,8 +9055,11 @@ Examples:
8295
9055
  Source network comes from the global -n/--network flag. Use --to-network for the destination chain.
8296
9056
  For same-chain token exchanges, use 'alchemy evm swap'.
8297
9057
 
9058
+ Tip: use 'alchemy evm token <SYMBOL>' to resolve common token addresses
9059
+ (ETH, USDC, WETH, USDT, DAI, \u2026) per chain.
9060
+
8298
9061
  Examples:
8299
- alchemy xchain bridge execute --from ${NATIVE_TOKEN_ADDRESS3} --to ${NATIVE_TOKEN_ADDRESS3} --amount 0.1 --to-network base-mainnet -n eth-mainnet
9062
+ alchemy xchain bridge execute --from ${NATIVE_TOKEN_ADDRESS} --to ${NATIVE_TOKEN_ADDRESS} --amount 0.1 --to-network base-mainnet -n eth-mainnet
8300
9063
  alchemy xchain bridge execute --from <eth_usdc_address> --to <arb_usdc_address> --amount 100 --to-network arb-mainnet --gas-sponsored --gas-policy-id <id> -n eth-mainnet`
8301
9064
  ).action(async (_opts, cmd2) => {
8302
9065
  try {
@@ -9125,7 +9888,7 @@ async function flushProcessOutput() {
9125
9888
  }
9126
9889
  program.name("alchemy").description(
9127
9890
  "The Alchemy CLI lets you query blockchain data, call JSON-RPC methods, and manage your Alchemy configuration."
9128
- ).version("0.9.1", "-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(
9129
9892
  "-n, --network <network>",
9130
9893
  "Target network (default: eth-mainnet) (env: ALCHEMY_NETWORK)"
9131
9894
  ).option("--x402", "Use x402 wallet-based gateway auth").option(
@@ -9312,11 +10075,11 @@ ${styledLine}`;
9312
10075
  "wallet"
9313
10076
  ];
9314
10077
  if (!skipAppPrompt.includes(cmdName) && isInteractiveAllowed(program) && !opts.apiKey && !process.env.ALCHEMY_API_KEY) {
9315
- const { resolveAuthToken: resolveAuthToken2 } = await import("./resolve-FQ66OWT7.js");
10078
+ const { resolveAuthToken: resolveAuthToken2 } = await import("./resolve-REZCFZZ7.js");
9316
10079
  const authToken = resolveAuthToken2(cfg);
9317
10080
  const hasApiKey = Boolean(cfg.api_key?.trim() || cfg.app?.apiKey);
9318
10081
  if (authToken && !hasApiKey) {
9319
- const { selectAppAfterAuth } = await import("./auth-6BBITIOZ.js");
10082
+ const { selectAppAfterAuth } = await import("./auth-23OYLRWN.js");
9320
10083
  console.log("");
9321
10084
  console.log(` No app selected. Please select an app to continue.`);
9322
10085
  await selectAppAfterAuth(authToken);
@@ -9351,7 +10114,7 @@ ${styledLine}`;
9351
10114
  if (isInteractiveAllowed(program)) {
9352
10115
  let latestForInteractiveStartup = null;
9353
10116
  if (shouldRunOnboarding(program, cfg)) {
9354
- const { runOnboarding } = await import("./onboarding-ZLBWCNTB.js");
10117
+ const { runOnboarding } = await import("./onboarding-IJQ72DK7.js");
9355
10118
  const latest = getAvailableUpdateOnce();
9356
10119
  const completed = await runOnboarding(program, latest);
9357
10120
  updateShownDuringInteractiveStartup = Boolean(latest);
@@ -9365,7 +10128,7 @@ ${styledLine}`;
9365
10128
  latestForInteractiveStartup
9366
10129
  );
9367
10130
  }
9368
- const { startREPL } = await import("./interactive-IFPSMRMX.js");
10131
+ const { startREPL } = await import("./interactive-KLVEYTQM.js");
9369
10132
  program.exitOverride();
9370
10133
  program.configureOutput({
9371
10134
  writeErr: () => {