@alchemy/cli 0.9.2 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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-HRWD4V2P.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";
@@ -214,11 +222,11 @@ async function resolveENS(name, client) {
214
222
  if (dataHex.length < 64) {
215
223
  throw errInvalidArgs(`ENS name "${name}" could not be resolved.`);
216
224
  }
217
- const address2 = "0x" + dataHex.slice(24, 64);
218
- if (address2 === "0x0000000000000000000000000000000000000000") {
225
+ const address3 = "0x" + dataHex.slice(24, 64);
226
+ if (address3 === "0x0000000000000000000000000000000000000000") {
219
227
  throw errInvalidArgs(`ENS name "${name}" is not registered or has no address set.`);
220
228
  }
221
- return address2;
229
+ return address3;
222
230
  }
223
231
 
224
232
  // src/lib/validators.ts
@@ -259,10 +267,10 @@ async function readStdinLines(name) {
259
267
  }
260
268
  return lines;
261
269
  }
262
- function validateAddress(address2) {
263
- if (!ADDRESS_RE.test(address2)) {
270
+ function validateAddress(address3) {
271
+ if (!ADDRESS_RE.test(address3)) {
264
272
  throw errInvalidArgs(
265
- `Invalid address "${address2}". Expected 0x-prefixed 40-hex-character address.`
273
+ `Invalid address "${address3}". Expected 0x-prefixed 40-hex-character address.`
266
274
  );
267
275
  }
268
276
  }
@@ -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);
@@ -2026,14 +2034,14 @@ function formatWalletStatus(value) {
2026
2034
  function walletKeysDirPath() {
2027
2035
  return join(configDir(), WALLET_KEYS_DIR);
2028
2036
  }
2029
- function walletKeyPath(prefix, address2) {
2030
- const addr = address2.trim().toLowerCase().replace(/^0x/, "").replace(/[^a-z0-9]/g, "").slice(0, ADDRESS_SLICE_LEN);
2037
+ function walletKeyPath(prefix, address3) {
2038
+ const addr = address3.trim().toLowerCase().replace(/^0x/, "").replace(/[^a-z0-9]/g, "").slice(0, ADDRESS_SLICE_LEN);
2031
2039
  const addressTag = addr || "unknown";
2032
2040
  const fileName = `${prefix}-${addressTag}-${Date.now()}-${randomUUID().slice(0, UUID_SLICE_LEN)}.txt`;
2033
2041
  return join(walletKeysDirPath(), fileName);
2034
2042
  }
2035
- function persistWalletKey(prefix, privateKey, address2) {
2036
- const keyPath = walletKeyPath(prefix, address2);
2043
+ function persistWalletKey(prefix, privateKey, address3) {
2044
+ const keyPath = walletKeyPath(prefix, address3);
2037
2045
  mkdirSync(dirname(keyPath), { recursive: true, mode: 493 });
2038
2046
  writeFileSync(keyPath, privateKey + "\n", { mode: 384, flag: "wx" });
2039
2047
  return keyPath;
@@ -2144,11 +2152,11 @@ function importAndPersistWallet(path) {
2144
2152
  } catch {
2145
2153
  throw errInvalidArgs(`Could not read key file: ${path}`);
2146
2154
  }
2147
- const address2 = getEvmWalletAddress(key);
2148
- const keyPath = persistWalletKey("wallet-key", key, address2);
2155
+ const address3 = getEvmWalletAddress(key);
2156
+ const keyPath = persistWalletKey("wallet-key", key, address3);
2149
2157
  const cfg = load();
2150
- save({ ...cfg, wallet_key_file: keyPath, wallet_address: address2 });
2151
- return { address: address2, keyFile: keyPath };
2158
+ save({ ...cfg, wallet_key_file: keyPath, wallet_address: address3 });
2159
+ return { address: address3, keyFile: keyPath };
2152
2160
  }
2153
2161
  function hasValidSessionWithEvm() {
2154
2162
  const session = resolveWalletSession();
@@ -2568,43 +2576,42 @@ 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
- throw errInvalidArgs(
2592
- "Specify `--mode <session|local>` in non-interactive mode."
2593
- );
2599
+ mode = "session";
2600
+ } else {
2601
+ const choice = await promptSelect({
2602
+ message: "Choose a wallet to connect",
2603
+ options: [
2604
+ { value: "session", label: "Session wallet", hint: "Recommended \u2014 Alchemy-managed, more secure" },
2605
+ { value: "local", label: "Local wallet", hint: "Private key stored on this machine" }
2606
+ ],
2607
+ initialValue: "session",
2608
+ cancelMessage: "Wallet connect cancelled."
2609
+ });
2610
+ if (choice === null) throw new WalletConnectInterruptedError();
2611
+ mode = choice;
2594
2612
  }
2595
- const choice = await promptSelect({
2596
- message: "Choose a wallet to connect",
2597
- options: [
2598
- { value: "session", label: "Session wallet", hint: "Recommended \u2014 Alchemy-managed, more secure" },
2599
- { value: "local", label: "Local wallet", hint: "Private key stored on this machine" }
2600
- ],
2601
- initialValue: "session",
2602
- cancelMessage: "Wallet connect cancelled."
2603
- });
2604
- if (choice === null) throw new WalletConnectInterruptedError();
2605
- mode2 = choice;
2606
2613
  }
2607
- if (mode2 === "session") {
2614
+ if (mode === "session") {
2608
2615
  await runSessionConnect({
2609
2616
  program: program2,
2610
2617
  force,
@@ -3097,15 +3104,15 @@ async function requestJSON(url, options) {
3097
3104
  async function callApiData(apiKey, path, options = {}) {
3098
3105
  if (!apiKey) throw errAuthRequired();
3099
3106
  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);
3107
+ const base = override ? new URL(`/data/v1/${apiKey}/`, override) : new URL(`https://api.g.${getBaseDomain()}/data/v1/${apiKey}/`);
3108
+ const url = withQuery(new URL(path.replace(/^\//, ""), base), options.query);
3102
3109
  return requestJSON(url, { ...options, path });
3103
3110
  }
3104
3111
  async function callApiPrices(apiKey, path, options = {}) {
3105
3112
  if (!apiKey) throw errAuthRequired();
3106
3113
  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);
3114
+ const base = override ? new URL(`/prices/v1/${apiKey}/`, override) : new URL(`https://api.g.${getBaseDomain()}/prices/v1/${apiKey}/`);
3115
+ const url = withQuery(new URL(path.replace(/^\//, ""), base), options.query);
3109
3116
  return requestJSON(url, { ...options, path });
3110
3117
  }
3111
3118
  async function callNotify(token, path, options = {}) {
@@ -3114,8 +3121,8 @@ async function callNotify(token, path, options = {}) {
3114
3121
  "Webhook API key required. Set ALCHEMY_WEBHOOK_API_KEY (or ALCHEMY_NOTIFY_AUTH_TOKEN) or pass --webhook-api-key."
3115
3122
  );
3116
3123
  }
3117
- const base2 = new URL(`https://dashboard.${getBaseDomain()}/api/`);
3118
- const url = withQuery(new URL(path.replace(/^\//, ""), base2), options.query);
3124
+ const base = new URL(`https://dashboard.${getBaseDomain()}/api/`);
3125
+ const url = withQuery(new URL(path.replace(/^\//, ""), base), options.query);
3119
3126
  return requestJSON(url, {
3120
3127
  ...options,
3121
3128
  path,
@@ -4119,15 +4126,176 @@ function printAccountSummary(args) {
4119
4126
 
4120
4127
  // src/commands/send-solana.ts
4121
4128
  import { address as solAddress2 } from "@solana/kit";
4129
+
4130
+ // src/lib/solana-token.ts
4131
+ import {
4132
+ AccountRole as AccountRole2,
4133
+ address as address2,
4134
+ getAddressEncoder,
4135
+ getProgramDerivedAddress
4136
+ } from "@solana/kit";
4137
+ var SPL_TOKEN_PROGRAM_ADDRESS2 = address2("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
4138
+ var SPL_TOKEN_2022_PROGRAM_ADDRESS = address2("TokenzQdBNbLqP5VEhdkAS6EPYdWnYARjfkM8GoyZ2G");
4139
+ var ASSOCIATED_TOKEN_PROGRAM_ADDRESS = address2("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL");
4140
+ var SYSTEM_PROGRAM_ADDRESS2 = address2("11111111111111111111111111111111");
4141
+ var SUPPORTED_TOKEN_PROGRAMS = /* @__PURE__ */ new Set([
4142
+ SPL_TOKEN_PROGRAM_ADDRESS2,
4143
+ SPL_TOKEN_2022_PROGRAM_ADDRESS
4144
+ ]);
4145
+ async function deriveAssociatedTokenAccount(args) {
4146
+ const addressEncoder = getAddressEncoder();
4147
+ const [associatedTokenAccount] = await getProgramDerivedAddress({
4148
+ programAddress: ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
4149
+ seeds: [
4150
+ addressEncoder.encode(args.owner),
4151
+ addressEncoder.encode(args.tokenProgramAddress),
4152
+ addressEncoder.encode(args.mint)
4153
+ ]
4154
+ });
4155
+ return associatedTokenAccount;
4156
+ }
4157
+ async function fetchSplMintInfo(client, mint) {
4158
+ const account = await fetchParsedAccount(client, mint);
4159
+ if (!account) {
4160
+ throw errInvalidArgs(`SPL token mint ${mint} was not found on this network.`);
4161
+ }
4162
+ const tokenProgramAddress = address2(account.owner);
4163
+ assertSupportedTokenProgram(tokenProgramAddress);
4164
+ const data = parseAccountData(account.data);
4165
+ const decimals = data?.parsed?.info?.decimals;
4166
+ if (typeof decimals !== "number" || !Number.isInteger(decimals) || decimals < 0 || decimals > 255) {
4167
+ throw errInvalidArgs(`Could not read decimals for SPL token mint ${mint}.`);
4168
+ }
4169
+ return {
4170
+ mint,
4171
+ decimals,
4172
+ tokenProgramAddress
4173
+ };
4174
+ }
4175
+ async function fetchSplTokenAccountInfo(client, tokenAccount) {
4176
+ const account = await fetchParsedAccount(client, tokenAccount);
4177
+ if (!account) return null;
4178
+ const tokenProgramAddress = address2(account.owner);
4179
+ assertSupportedTokenProgram(tokenProgramAddress);
4180
+ const data = parseAccountData(account.data);
4181
+ const info = data?.parsed?.info;
4182
+ if (!info || data?.parsed?.type !== "account") {
4183
+ throw errInvalidArgs(`Account ${tokenAccount} is not an SPL token account.`);
4184
+ }
4185
+ const mint = readAddressField(info, "mint", `Account ${tokenAccount} is missing token mint metadata.`);
4186
+ const owner = readAddressField(info, "owner", `Account ${tokenAccount} is missing token owner metadata.`);
4187
+ return {
4188
+ address: tokenAccount,
4189
+ mint,
4190
+ owner,
4191
+ tokenProgramAddress
4192
+ };
4193
+ }
4194
+ function buildCreateAssociatedTokenAccountIdempotentInstruction(args) {
4195
+ return {
4196
+ programAddress: ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
4197
+ accounts: [
4198
+ { address: args.payer.address, role: AccountRole2.WRITABLE_SIGNER },
4199
+ { address: args.associatedTokenAccount, role: AccountRole2.WRITABLE },
4200
+ { address: args.owner, role: AccountRole2.READONLY },
4201
+ { address: args.mint, role: AccountRole2.READONLY },
4202
+ { address: SYSTEM_PROGRAM_ADDRESS2, role: AccountRole2.READONLY },
4203
+ { address: args.tokenProgramAddress, role: AccountRole2.READONLY }
4204
+ ],
4205
+ data: new Uint8Array([1])
4206
+ };
4207
+ }
4208
+ function buildSplTokenTransferCheckedInstruction(args) {
4209
+ if (!Number.isInteger(args.decimals) || args.decimals < 0 || args.decimals > 255) {
4210
+ throw errInvalidArgs("Token decimals must be an integer between 0 and 255.");
4211
+ }
4212
+ return {
4213
+ programAddress: args.tokenProgramAddress,
4214
+ accounts: [
4215
+ { address: args.sourceTokenAccount, role: AccountRole2.WRITABLE },
4216
+ { address: args.mint, role: AccountRole2.READONLY },
4217
+ { address: args.destinationTokenAccount, role: AccountRole2.WRITABLE },
4218
+ { address: args.owner.address, role: AccountRole2.READONLY_SIGNER }
4219
+ ],
4220
+ data: new Uint8Array([
4221
+ 12,
4222
+ ...encodeU64LE2(args.amount),
4223
+ args.decimals
4224
+ ])
4225
+ };
4226
+ }
4227
+ function assertTokenAccountMatches(args) {
4228
+ if (args.account.mint !== args.expectedMint) {
4229
+ throw errInvalidArgs(
4230
+ `${args.label} ${args.account.address} is for mint ${args.account.mint}, expected ${args.expectedMint}.`
4231
+ );
4232
+ }
4233
+ if (args.expectedOwner && args.account.owner !== args.expectedOwner) {
4234
+ throw errInvalidArgs(
4235
+ `${args.label} ${args.account.address} is owned by ${args.account.owner}, expected ${args.expectedOwner}.`
4236
+ );
4237
+ }
4238
+ }
4239
+ function assertSupportedTokenProgram(tokenProgramAddress) {
4240
+ if (!SUPPORTED_TOKEN_PROGRAMS.has(tokenProgramAddress)) {
4241
+ throw errInvalidArgs(
4242
+ `Unsupported Solana token program ${tokenProgramAddress}. Only SPL Token and Token-2022 mints are supported.`
4243
+ );
4244
+ }
4245
+ }
4246
+ async function fetchParsedAccount(client, accountAddress) {
4247
+ const result = await client.call("getAccountInfo", [
4248
+ accountAddress,
4249
+ { encoding: "jsonParsed" }
4250
+ ]);
4251
+ return result.value;
4252
+ }
4253
+ function parseAccountData(data) {
4254
+ if (!data || typeof data !== "object" || Array.isArray(data)) return null;
4255
+ return data;
4256
+ }
4257
+ function readAddressField(info, field, errorMessage) {
4258
+ const value = info[field];
4259
+ if (typeof value !== "string") {
4260
+ throw errInvalidArgs(errorMessage);
4261
+ }
4262
+ return address2(value);
4263
+ }
4264
+ function encodeU64LE2(value) {
4265
+ if (value < 0n || value > 0xffffffffffffffffn) {
4266
+ throw errInvalidArgs("Amount must fit in an unsigned 64-bit integer.");
4267
+ }
4268
+ const bytes = new Uint8Array(8);
4269
+ let remaining = value;
4270
+ for (let i = 0; i < bytes.length; i++) {
4271
+ bytes[i] = Number(remaining & 0xffn);
4272
+ remaining >>= 8n;
4273
+ }
4274
+ return bytes;
4275
+ }
4276
+
4277
+ // src/commands/send-solana.ts
4122
4278
  function registerSolanaSend(program2) {
4123
- const sendCmd = program2.command("send <to> <amount>").description("Send SOL to an address").option("--token <address>", "SPL token contract address (not yet supported)").option("--fee-sponsored", "Enable Solana fee sponsorship").option("--fee-policy-id <id>", "Solana fee policy ID for sponsorship");
4279
+ const sendCmd = program2.command("send <to> <amount>").description("Send SOL or SPL tokens to an address").option("--token <mint>", "SPL token mint address (omit for native SOL)").option("--dry-run", "Preview transaction without signing or sending").option("--fail-if-associated-token-account-missing", "Fail if the recipient associated token account is missing").option("--from-token-account <address>", "Source SPL token account (defaults to sender associated token account)").option("--recipient-token-account <address>", "Destination SPL token account (defaults to recipient associated token account)").option("--fee-sponsored", "Enable Solana fee sponsorship").option("--fee-policy-id <id>", "Solana fee policy ID for sponsorship").addHelpText(
4280
+ "after",
4281
+ `
4282
+ Examples:
4283
+ alchemy solana send <pubkey> 0.1
4284
+ alchemy solana send <pubkey> 10 --token <mint>
4285
+ alchemy solana send <pubkey> 10 --token <mint> --dry-run
4286
+ alchemy solana send <pubkey> 10 --token <mint> --fail-if-associated-token-account-missing`
4287
+ );
4124
4288
  addSignerOption(sendCmd);
4125
4289
  sendCmd.action(
4126
4290
  async (toArg, amountArg, _opts, actionCommand) => {
4127
4291
  try {
4128
4292
  const opts = actionCommand.opts();
4129
4293
  await performSolanaSend(actionCommand, toArg, amountArg, opts.token, {
4130
- signer: parseSignerOpt(opts.signer)
4294
+ signer: parseSignerOpt(opts.signer),
4295
+ dryRun: opts.dryRun,
4296
+ failIfAssociatedTokenAccountMissing: opts.failIfAssociatedTokenAccountMissing,
4297
+ fromTokenAccount: opts.fromTokenAccount,
4298
+ recipientTokenAccount: opts.recipientTokenAccount
4131
4299
  });
4132
4300
  } catch (err) {
4133
4301
  exitWithError(err);
@@ -4136,75 +4304,378 @@ function registerSolanaSend(program2) {
4136
4304
  );
4137
4305
  }
4138
4306
  async function performSolanaSend(program2, toArg, amountArg, tokenAddress, opts = {}) {
4139
- if (tokenAddress) {
4140
- throw errInvalidArgs("SPL token transfers are not yet supported. Omit --token for native SOL transfers.");
4141
- }
4307
+ validateSolanaTokenOptions(tokenAddress, opts);
4142
4308
  const signer = await resolveSolanaSigner(program2, opts.signer);
4143
4309
  validateSolanaAddress(toArg);
4144
4310
  const to = solAddress2(toArg);
4145
4311
  const network = resolveSolanaNetwork(program2);
4146
- const symbol = nativeTokenSymbol(network);
4147
- const lamports = parseAmount(amountArg, SOL_DECIMALS);
4148
- const instruction = buildSolTransferInstruction(
4149
- { address: solAddress2(signer.address) },
4312
+ const { sponsored, feePolicyId } = await resolveSolanaFeeSponsorship(program2);
4313
+ const client = clientFromFlags(program2, { forceNetwork: network });
4314
+ if (tokenAddress) {
4315
+ await performSplTokenSend({
4316
+ client,
4317
+ signer,
4318
+ to,
4319
+ toArg,
4320
+ amountArg,
4321
+ tokenAddress,
4322
+ network,
4323
+ sponsored,
4324
+ feePolicyId,
4325
+ opts
4326
+ });
4327
+ return;
4328
+ }
4329
+ await performNativeSolSend({
4330
+ client,
4331
+ signer,
4150
4332
  to,
4333
+ toArg,
4334
+ amountArg,
4335
+ network,
4336
+ sponsored,
4337
+ feePolicyId,
4338
+ dryRun: opts.dryRun
4339
+ });
4340
+ }
4341
+ async function performNativeSolSend(args) {
4342
+ const symbol = nativeTokenSymbol(args.network);
4343
+ const lamports = parseAmount(args.amountArg, SOL_DECIMALS);
4344
+ const instruction = buildSolTransferInstruction(
4345
+ { address: solAddress2(args.signer.address) },
4346
+ args.to,
4151
4347
  lamports
4152
4348
  );
4153
- const { sponsored, feePolicyId } = await resolveSolanaFeeSponsorship(program2);
4154
- const client = clientFromFlags(program2, { forceNetwork: network });
4349
+ if (args.dryRun) {
4350
+ printNativeDryRun({
4351
+ from: args.signer.address,
4352
+ to: args.toArg,
4353
+ amount: args.amountArg,
4354
+ symbol,
4355
+ network: args.network,
4356
+ sponsored: args.sponsored
4357
+ });
4358
+ return;
4359
+ }
4155
4360
  const result = await withSpinner(
4156
4361
  "Sending transaction\u2026",
4157
4362
  "Transaction submitted",
4158
4363
  async () => {
4159
- if (signer.type === "session") {
4364
+ if (args.signer.type === "session") {
4160
4365
  return await buildAndSendSolanaTransactionWithSession({
4161
- client,
4366
+ client: args.client,
4162
4367
  instructions: [instruction],
4163
- session: signer.session,
4164
- authToken: signer.authToken,
4165
- sponsored,
4166
- gasPolicyId: feePolicyId
4368
+ session: args.signer.session,
4369
+ authToken: args.signer.authToken,
4370
+ sponsored: args.sponsored,
4371
+ gasPolicyId: args.feePolicyId
4167
4372
  });
4168
4373
  }
4169
4374
  return await buildAndSendSolanaTransaction({
4170
- client,
4375
+ client: args.client,
4171
4376
  instructions: [instruction],
4172
- senderKeyBytes: signer.keyBytes,
4173
- sponsored,
4174
- gasPolicyId: feePolicyId
4377
+ senderKeyBytes: args.signer.keyBytes,
4378
+ sponsored: args.sponsored,
4379
+ gasPolicyId: args.feePolicyId
4175
4380
  });
4176
4381
  }
4177
4382
  );
4178
4383
  const confirmed = await withSpinner(
4179
4384
  "Waiting for confirmation\u2026",
4180
4385
  "Confirmation status received",
4181
- () => waitForSolanaConfirmation(client, result.signature)
4386
+ () => waitForSolanaConfirmation(args.client, result.signature)
4387
+ );
4388
+ printNativeResult({
4389
+ result,
4390
+ to: args.toArg,
4391
+ amount: args.amountArg,
4392
+ symbol,
4393
+ network: args.network,
4394
+ sponsored: args.sponsored,
4395
+ status: confirmed ? "confirmed" : "pending"
4396
+ });
4397
+ }
4398
+ function validateSolanaTokenOptions(tokenAddress, opts) {
4399
+ if (tokenAddress) return;
4400
+ const splOnlyFlags = [
4401
+ opts.fromTokenAccount ? "--from-token-account" : void 0,
4402
+ opts.recipientTokenAccount ? "--recipient-token-account" : void 0,
4403
+ opts.failIfAssociatedTokenAccountMissing ? "--fail-if-associated-token-account-missing" : void 0
4404
+ ].filter((flag) => flag !== void 0);
4405
+ if (splOnlyFlags.length === 0) return;
4406
+ throw errInvalidArgs(
4407
+ `${splOnlyFlags.join(", ")} ${splOnlyFlags.length === 1 ? "requires" : "require"} --token <mint>.`
4408
+ );
4409
+ }
4410
+ async function performSplTokenSend(args) {
4411
+ validateSolanaAddress(args.tokenAddress);
4412
+ if (args.opts.fromTokenAccount) validateSolanaAddress(args.opts.fromTokenAccount);
4413
+ if (args.opts.recipientTokenAccount) validateSolanaAddress(args.opts.recipientTokenAccount);
4414
+ const mint = solAddress2(args.tokenAddress);
4415
+ const owner = solAddress2(args.signer.address);
4416
+ const mintInfo = await fetchSplMintInfo(args.client, mint);
4417
+ const amount = parseAmount(args.amountArg, mintInfo.decimals);
4418
+ const plan = await buildSplSendPlan({
4419
+ client: args.client,
4420
+ owner,
4421
+ recipient: args.to,
4422
+ mint,
4423
+ amount,
4424
+ decimals: mintInfo.decimals,
4425
+ tokenProgramAddress: mintInfo.tokenProgramAddress,
4426
+ failIfAssociatedTokenAccountMissing: Boolean(args.opts.failIfAssociatedTokenAccountMissing),
4427
+ fromTokenAccount: args.opts.fromTokenAccount ? solAddress2(args.opts.fromTokenAccount) : void 0,
4428
+ recipientTokenAccount: args.opts.recipientTokenAccount ? solAddress2(args.opts.recipientTokenAccount) : void 0
4429
+ });
4430
+ if (args.opts.dryRun) {
4431
+ printSplDryRun({
4432
+ from: args.signer.address,
4433
+ to: args.toArg,
4434
+ amount: args.amountArg,
4435
+ network: args.network,
4436
+ sponsored: args.sponsored,
4437
+ plan
4438
+ });
4439
+ return;
4440
+ }
4441
+ const result = await submitSolanaInstructions({
4442
+ client: args.client,
4443
+ signer: args.signer,
4444
+ instructions: plan.instructions,
4445
+ sponsored: args.sponsored,
4446
+ feePolicyId: args.feePolicyId
4447
+ });
4448
+ const confirmed = await withSpinner(
4449
+ "Waiting for confirmation\u2026",
4450
+ "Confirmation status received",
4451
+ () => waitForSolanaConfirmation(args.client, result.signature)
4452
+ );
4453
+ printSplResult({
4454
+ result,
4455
+ to: args.toArg,
4456
+ amount: args.amountArg,
4457
+ network: args.network,
4458
+ sponsored: args.sponsored,
4459
+ plan,
4460
+ status: confirmed ? "confirmed" : "pending"
4461
+ });
4462
+ }
4463
+ async function buildSplSendPlan(args) {
4464
+ const sourceTokenAccount = args.fromTokenAccount ?? await deriveAssociatedTokenAccount({
4465
+ owner: args.owner,
4466
+ mint: args.mint,
4467
+ tokenProgramAddress: args.tokenProgramAddress
4468
+ });
4469
+ const sourceAccount = await fetchSplTokenAccountInfo(args.client, sourceTokenAccount);
4470
+ if (!sourceAccount) {
4471
+ throw errInvalidArgs(
4472
+ `Source token account ${sourceTokenAccount} was not found. Fund the sender's associated token account for mint ${args.mint} and retry.`
4473
+ );
4474
+ }
4475
+ assertTokenAccountMatches({
4476
+ account: sourceAccount,
4477
+ expectedMint: args.mint,
4478
+ expectedOwner: args.owner,
4479
+ label: "Source token account"
4480
+ });
4481
+ const destinationTokenAccount = args.recipientTokenAccount ?? await deriveAssociatedTokenAccount({
4482
+ owner: args.recipient,
4483
+ mint: args.mint,
4484
+ tokenProgramAddress: args.tokenProgramAddress
4485
+ });
4486
+ const destinationAccount = await fetchSplTokenAccountInfo(args.client, destinationTokenAccount);
4487
+ const createDestinationTokenAccount = !destinationAccount && !args.recipientTokenAccount && !args.failIfAssociatedTokenAccountMissing;
4488
+ if (!destinationAccount && args.recipientTokenAccount) {
4489
+ throw errInvalidArgs(`Recipient token account ${destinationTokenAccount} was not found.`);
4490
+ }
4491
+ if (!destinationAccount && args.failIfAssociatedTokenAccountMissing) {
4492
+ throw errInvalidArgs(
4493
+ `Recipient associated token account ${destinationTokenAccount} does not exist. Omit --fail-if-associated-token-account-missing to create it automatically.`
4494
+ );
4495
+ }
4496
+ if (destinationAccount) {
4497
+ assertTokenAccountMatches({
4498
+ account: destinationAccount,
4499
+ expectedMint: args.mint,
4500
+ ...args.recipientTokenAccount ? {} : { expectedOwner: args.recipient },
4501
+ label: "Recipient token account"
4502
+ });
4503
+ }
4504
+ const instructions = [];
4505
+ if (createDestinationTokenAccount) {
4506
+ instructions.push(buildCreateAssociatedTokenAccountIdempotentInstruction({
4507
+ payer: { address: args.owner },
4508
+ associatedTokenAccount: destinationTokenAccount,
4509
+ owner: args.recipient,
4510
+ mint: args.mint,
4511
+ tokenProgramAddress: args.tokenProgramAddress
4512
+ }));
4513
+ }
4514
+ instructions.push(buildSplTokenTransferCheckedInstruction({
4515
+ sourceTokenAccount,
4516
+ mint: args.mint,
4517
+ destinationTokenAccount,
4518
+ owner: { address: args.owner },
4519
+ amount: args.amount,
4520
+ decimals: args.decimals,
4521
+ tokenProgramAddress: args.tokenProgramAddress
4522
+ }));
4523
+ return {
4524
+ instructions,
4525
+ mint: args.mint,
4526
+ tokenProgramAddress: args.tokenProgramAddress,
4527
+ sourceTokenAccount,
4528
+ destinationTokenAccount,
4529
+ createdDestinationTokenAccount: createDestinationTokenAccount,
4530
+ decimals: args.decimals
4531
+ };
4532
+ }
4533
+ async function submitSolanaInstructions(args) {
4534
+ const result = await withSpinner(
4535
+ "Sending transaction\u2026",
4536
+ "Transaction submitted",
4537
+ async () => {
4538
+ if (args.signer.type === "session") {
4539
+ return await buildAndSendSolanaTransactionWithSession({
4540
+ client: args.client,
4541
+ instructions: args.instructions,
4542
+ session: args.signer.session,
4543
+ authToken: args.signer.authToken,
4544
+ sponsored: args.sponsored,
4545
+ gasPolicyId: args.feePolicyId
4546
+ });
4547
+ }
4548
+ return await buildAndSendSolanaTransaction({
4549
+ client: args.client,
4550
+ instructions: args.instructions,
4551
+ senderKeyBytes: args.signer.keyBytes,
4552
+ sponsored: args.sponsored,
4553
+ gasPolicyId: args.feePolicyId
4554
+ });
4555
+ }
4182
4556
  );
4557
+ return result;
4558
+ }
4559
+ function printNativeDryRun(args) {
4183
4560
  if (isJSONMode()) {
4184
4561
  printJSON({
4185
- from: result.fromAddress,
4186
- to: toArg,
4187
- amount: amountArg,
4188
- token: symbol,
4189
- network,
4190
- sponsored,
4191
- signature: result.signature,
4192
- status: confirmed ? "confirmed" : "pending"
4562
+ dryRun: true,
4563
+ action: "solana-send",
4564
+ from: args.from,
4565
+ to: args.to,
4566
+ amount: args.amount,
4567
+ token: args.symbol,
4568
+ network: args.network,
4569
+ sponsored: args.sponsored,
4570
+ instructions: ["transferSol"]
4193
4571
  });
4194
- } else {
4195
- const pairs = [
4196
- ["From", result.fromAddress],
4197
- ["To", toArg],
4198
- ["Amount", green(`${amountArg} ${symbol}`)],
4199
- ["Network", network]
4200
- ];
4201
- if (sponsored) {
4202
- pairs.push(["Fee", green("Sponsored")]);
4203
- }
4204
- pairs.push(["Signature", result.signature]);
4205
- pairs.push(["Status", confirmed ? `${successBadge()} ${green("Confirmed")}` : "Pending"]);
4206
- printKeyValue(pairs);
4572
+ return;
4207
4573
  }
4574
+ const pairs = [
4575
+ ["Dry Run", "yes"],
4576
+ ["From", args.from],
4577
+ ["To", args.to],
4578
+ ["Amount", green(`${args.amount} ${args.symbol}`)],
4579
+ ["Network", args.network],
4580
+ ["Instructions", "transferSol"]
4581
+ ];
4582
+ if (args.sponsored) pairs.push(["Fee", green("Sponsored")]);
4583
+ printKeyValue(pairs);
4584
+ }
4585
+ function printNativeResult(args) {
4586
+ if (isJSONMode()) {
4587
+ printJSON({
4588
+ from: args.result.fromAddress,
4589
+ to: args.to,
4590
+ amount: args.amount,
4591
+ token: args.symbol,
4592
+ network: args.network,
4593
+ sponsored: args.sponsored,
4594
+ signature: args.result.signature,
4595
+ status: args.status
4596
+ });
4597
+ return;
4598
+ }
4599
+ const pairs = [
4600
+ ["From", args.result.fromAddress],
4601
+ ["To", args.to],
4602
+ ["Amount", green(`${args.amount} ${args.symbol}`)],
4603
+ ["Network", args.network]
4604
+ ];
4605
+ if (args.sponsored) pairs.push(["Fee", green("Sponsored")]);
4606
+ pairs.push(["Signature", args.result.signature]);
4607
+ pairs.push(["Status", args.status === "confirmed" ? `${successBadge()} ${green("Confirmed")}` : "Pending"]);
4608
+ printKeyValue(pairs);
4609
+ }
4610
+ function printSplDryRun(args) {
4611
+ const instructions = args.plan.createdDestinationTokenAccount ? ["createAssociatedTokenAccountIdempotent", "transferChecked"] : ["transferChecked"];
4612
+ if (isJSONMode()) {
4613
+ printJSON({
4614
+ dryRun: true,
4615
+ action: "solana-send",
4616
+ from: args.from,
4617
+ to: args.to,
4618
+ amount: args.amount,
4619
+ token: args.plan.mint,
4620
+ tokenAddress: args.plan.mint,
4621
+ network: args.network,
4622
+ sponsored: args.sponsored,
4623
+ tokenProgramAddress: args.plan.tokenProgramAddress,
4624
+ sourceTokenAccount: args.plan.sourceTokenAccount,
4625
+ destinationTokenAccount: args.plan.destinationTokenAccount,
4626
+ createdDestinationTokenAccount: args.plan.createdDestinationTokenAccount,
4627
+ instructions
4628
+ });
4629
+ return;
4630
+ }
4631
+ const pairs = [
4632
+ ["Dry Run", "yes"],
4633
+ ["From", args.from],
4634
+ ["To", args.to],
4635
+ ["Amount", green(`${args.amount} ${args.plan.mint}`)],
4636
+ ["Mint", args.plan.mint],
4637
+ ["Source Token Account", args.plan.sourceTokenAccount],
4638
+ ["Destination Token Account", args.plan.destinationTokenAccount],
4639
+ ["Created Destination Token Account", args.plan.createdDestinationTokenAccount ? "yes" : "no"],
4640
+ ["Network", args.network],
4641
+ ["Instructions", instructions.join(", ")]
4642
+ ];
4643
+ if (args.sponsored) pairs.push(["Fee", green("Sponsored")]);
4644
+ printKeyValue(pairs);
4645
+ }
4646
+ function printSplResult(args) {
4647
+ if (isJSONMode()) {
4648
+ printJSON({
4649
+ from: args.result.fromAddress,
4650
+ to: args.to,
4651
+ amount: args.amount,
4652
+ token: args.plan.mint,
4653
+ tokenAddress: args.plan.mint,
4654
+ network: args.network,
4655
+ sponsored: args.sponsored,
4656
+ tokenProgramAddress: args.plan.tokenProgramAddress,
4657
+ sourceTokenAccount: args.plan.sourceTokenAccount,
4658
+ destinationTokenAccount: args.plan.destinationTokenAccount,
4659
+ createdDestinationTokenAccount: args.plan.createdDestinationTokenAccount,
4660
+ signature: args.result.signature,
4661
+ status: args.status
4662
+ });
4663
+ return;
4664
+ }
4665
+ const pairs = [
4666
+ ["From", args.result.fromAddress],
4667
+ ["To", args.to],
4668
+ ["Amount", green(`${args.amount} ${args.plan.mint}`)],
4669
+ ["Mint", args.plan.mint],
4670
+ ["Source Token Account", args.plan.sourceTokenAccount],
4671
+ ["Destination Token Account", args.plan.destinationTokenAccount],
4672
+ ["Created Destination Token Account", args.plan.createdDestinationTokenAccount ? "yes" : "no"],
4673
+ ["Network", args.network]
4674
+ ];
4675
+ if (args.sponsored) pairs.push(["Fee", green("Sponsored")]);
4676
+ pairs.push(["Signature", args.result.signature]);
4677
+ pairs.push(["Status", args.status === "confirmed" ? `${successBadge()} ${green("Confirmed")}` : "Pending"]);
4678
+ printKeyValue(pairs);
4208
4679
  }
4209
4680
  async function resolveSolanaSigner(program2, signer) {
4210
4681
  if (signer === "session") {
@@ -4267,51 +4738,10 @@ import { createSmartWalletClient } from "@alchemy/wallet-apis";
4267
4738
  import { privateKeyToAccount as privateKeyToAccount2 } from "viem/accounts";
4268
4739
 
4269
4740
  // 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
4741
  function networkToChain(network) {
4312
- const chain = NETWORK_TO_CHAIN[network];
4742
+ const chain = walletNetworkToChain(network);
4313
4743
  if (!chain) {
4314
- const supported = Object.keys(NETWORK_TO_CHAIN).sort().join(", ");
4744
+ const supported = supportedWalletNetworks().join(", ");
4315
4745
  throw errInvalidArgs(
4316
4746
  `Network "${network}" is not supported for wallet operations. Supported networks: ${supported}`
4317
4747
  );
@@ -4499,9 +4929,9 @@ async function debugRecoveredTypedDataAddress(args) {
4499
4929
  }
4500
4930
  function createDelegatedAccount(args) {
4501
4931
  const sessionBinding = buildSessionBindingInput(args.session);
4502
- const address2 = args.session.evmAddress;
4932
+ const address3 = args.session.evmAddress;
4503
4933
  return toAccount({
4504
- address: address2,
4934
+ address: address3,
4505
4935
  async signTransaction() {
4506
4936
  throw errInvalidArgs(
4507
4937
  "Delegated signer does not support direct transaction signing. Use wallet commands that execute through Alchemy smart wallets."
@@ -4532,7 +4962,7 @@ function createDelegatedAccount(args) {
4532
4962
  message: remoteMessage.message,
4533
4963
  encoding: remoteMessage.encoding,
4534
4964
  signature: signedMessage,
4535
- expectedAddress: address2
4965
+ expectedAddress: address3
4536
4966
  });
4537
4967
  return signedMessage;
4538
4968
  },
@@ -4568,7 +4998,7 @@ function createDelegatedAccount(args) {
4568
4998
  await debugRecoveredTypedDataAddress({
4569
4999
  typedData: serializedTypedData,
4570
5000
  signature: typedDataSignature,
4571
- expectedAddress: address2
5001
+ expectedAddress: address3
4572
5002
  });
4573
5003
  return typedDataSignature;
4574
5004
  },
@@ -5102,6 +5532,517 @@ function formatError(error) {
5102
5532
  }
5103
5533
  }
5104
5534
 
5535
+ // ../../packages/sdk/dist/data/index.js
5536
+ var DEFAULT_DATA_TIMEOUT_MS = 3e4;
5537
+ var DEFAULT_BREADCRUMB_HEADER = "alchemy-sdk";
5538
+ var DataApiError = class extends Error {
5539
+ status;
5540
+ constructor(status, message) {
5541
+ super(message);
5542
+ this.status = status;
5543
+ this.name = "DataApiError";
5544
+ }
5545
+ };
5546
+ async function dataGet(baseUrl, apiKey, path, params, options = {}) {
5547
+ const url = new URL(`${baseUrl}/${apiKey}${path}`);
5548
+ if (params) {
5549
+ for (const [key, value] of Object.entries(params)) {
5550
+ if (value === void 0)
5551
+ continue;
5552
+ if (Array.isArray(value)) {
5553
+ for (const item of value)
5554
+ url.searchParams.append(key, item);
5555
+ } else {
5556
+ url.searchParams.set(key, value);
5557
+ }
5558
+ }
5559
+ }
5560
+ const resp = await dataFetch(url.toString(), "GET", void 0, options);
5561
+ return resp.json();
5562
+ }
5563
+ async function dataPost(baseUrl, apiKey, path, body, options = {}) {
5564
+ const resp = await dataFetch(`${baseUrl}/${apiKey}${path}`, "POST", body, options);
5565
+ return resp.json();
5566
+ }
5567
+ function nftBaseUrl(network, options = {}) {
5568
+ validateNetwork(network);
5569
+ return `https://${network}.${getGatewayDomain(options)}/nft/v3`;
5570
+ }
5571
+ function pricesBaseUrl(options = {}) {
5572
+ return `https://api.${getGatewayDomain(options)}/prices/v1`;
5573
+ }
5574
+ function portfolioBaseUrl(options = {}) {
5575
+ return `https://api.${getGatewayDomain(options)}/data/v1`;
5576
+ }
5577
+ function createAlchemyDataClient(apiKey, options = {}) {
5578
+ return new AlchemyDataClient(apiKey, options);
5579
+ }
5580
+ var AlchemyDataClient = class {
5581
+ apiKey;
5582
+ options;
5583
+ nft;
5584
+ prices;
5585
+ portfolio;
5586
+ constructor(apiKey, options = {}) {
5587
+ this.apiKey = apiKey;
5588
+ this.options = options;
5589
+ this.nft = new NftApiClient(apiKey, options);
5590
+ this.prices = new PricesApiClient(apiKey, options);
5591
+ this.portfolio = new PortfolioApiClient(apiKey, options);
5592
+ }
5593
+ };
5594
+ var NftApiClient = class {
5595
+ apiKey;
5596
+ options;
5597
+ constructor(apiKey, options = {}) {
5598
+ this.apiKey = apiKey;
5599
+ this.options = options;
5600
+ }
5601
+ getNFTsForOwner(network, params) {
5602
+ return this.get(network, "/getNFTsForOwner", params);
5603
+ }
5604
+ getNFTsForContract(network, params) {
5605
+ return this.get(network, "/getNFTsForContract", params);
5606
+ }
5607
+ getNFTMetadata(network, params) {
5608
+ return this.get(network, "/getNFTMetadata", params);
5609
+ }
5610
+ getNFTMetadataBatch(network, body) {
5611
+ return this.post(network, "/getNFTMetadataBatch", body);
5612
+ }
5613
+ getContractMetadata(network, params) {
5614
+ return this.get(network, "/getContractMetadata", params);
5615
+ }
5616
+ getOwnersForNFT(network, params) {
5617
+ return this.get(network, "/getOwnersForNFT", params);
5618
+ }
5619
+ getOwnersForContract(network, params) {
5620
+ return this.get(network, "/getOwnersForContract", params);
5621
+ }
5622
+ getFloorPrice(network, params) {
5623
+ return this.get(network, "/getFloorPrice", params);
5624
+ }
5625
+ isSpamContract(network, params) {
5626
+ return this.get(network, "/isSpamContract", params);
5627
+ }
5628
+ searchContractMetadata(network, params) {
5629
+ return this.get(network, "/searchContractMetadata", params);
5630
+ }
5631
+ getNFTSales(network, params) {
5632
+ return this.get(network, "/getNFTSales", params);
5633
+ }
5634
+ getContractsForOwner(network, params) {
5635
+ return this.get(network, "/getContractsForOwner", params);
5636
+ }
5637
+ getNFTsForCollection(network, params) {
5638
+ return this.get(network, "/getNFTsForCollection", params);
5639
+ }
5640
+ getCollectionMetadata(network, params) {
5641
+ return this.get(network, "/getCollectionMetadata", params);
5642
+ }
5643
+ getContractMetadataBatch(network, body) {
5644
+ return this.post(network, "/getContractMetadataBatch", body);
5645
+ }
5646
+ getSpamContracts(network) {
5647
+ return this.get(network, "/getSpamContracts", {});
5648
+ }
5649
+ isAirdropNFT(network, params) {
5650
+ return this.get(network, "/isAirdropNFT", params);
5651
+ }
5652
+ summarizeNFTAttributes(network, params) {
5653
+ return this.get(network, "/summarizeNFTAttributes", params);
5654
+ }
5655
+ isHolderOfContract(network, params) {
5656
+ return this.get(network, "/isHolderOfContract", params);
5657
+ }
5658
+ computeRarity(network, params) {
5659
+ return this.get(network, "/computeRarity", params);
5660
+ }
5661
+ getCollectionsForOwner(network, params) {
5662
+ return this.get(network, "/getCollectionsForOwner", params);
5663
+ }
5664
+ get(network, path, params) {
5665
+ return dataGet(nftBaseUrl(network, this.options), this.apiKey, path, params, this.options);
5666
+ }
5667
+ post(network, path, body) {
5668
+ return dataPost(nftBaseUrl(network, this.options), this.apiKey, path, body, this.options);
5669
+ }
5670
+ };
5671
+ var PricesApiClient = class {
5672
+ apiKey;
5673
+ options;
5674
+ constructor(apiKey, options = {}) {
5675
+ this.apiKey = apiKey;
5676
+ this.options = options;
5677
+ }
5678
+ getTokenPricesBySymbol(params) {
5679
+ return dataGet(pricesBaseUrl(this.options), this.apiKey, "/tokens/by-symbol", params, this.options);
5680
+ }
5681
+ getTokenPricesByAddress(body) {
5682
+ return dataPost(pricesBaseUrl(this.options), this.apiKey, "/tokens/by-address", body, this.options);
5683
+ }
5684
+ getHistoricalTokenPrices(body) {
5685
+ return dataPost(pricesBaseUrl(this.options), this.apiKey, "/tokens/historical", body, this.options);
5686
+ }
5687
+ };
5688
+ var PortfolioApiClient = class {
5689
+ apiKey;
5690
+ options;
5691
+ constructor(apiKey, options = {}) {
5692
+ this.apiKey = apiKey;
5693
+ this.options = options;
5694
+ }
5695
+ getTokensByAddress(body) {
5696
+ return this.post("/assets/tokens/by-address", body);
5697
+ }
5698
+ getTokenBalancesByAddress(body) {
5699
+ return this.post("/assets/tokens/balances/by-address", body);
5700
+ }
5701
+ getNFTsByAddress(body) {
5702
+ return this.post("/assets/nfts/by-address", body);
5703
+ }
5704
+ getNFTContractsByAddress(body) {
5705
+ return this.post("/assets/nfts/contracts/by-address", body);
5706
+ }
5707
+ post(path, body) {
5708
+ return dataPost(portfolioBaseUrl(this.options), this.apiKey, path, body, this.options);
5709
+ }
5710
+ };
5711
+ async function dataFetch(url, method, body, options) {
5712
+ const fetchFn = options.fetchFn ?? fetch;
5713
+ const resp = await fetchFn(url, {
5714
+ method,
5715
+ headers: {
5716
+ ...body !== void 0 && { "Content-Type": "application/json" },
5717
+ Accept: "application/json",
5718
+ "x-alchemy-client-breadcrumb": options.breadcrumb ?? DEFAULT_BREADCRUMB_HEADER
5719
+ },
5720
+ ...body !== void 0 && { body: JSON.stringify(body) },
5721
+ signal: AbortSignal.timeout(options.timeoutMs ?? DEFAULT_DATA_TIMEOUT_MS)
5722
+ });
5723
+ if (!resp.ok) {
5724
+ const text = await resp.text().catch(() => "");
5725
+ throw new DataApiError(resp.status, text || `HTTP ${resp.status}`);
5726
+ }
5727
+ return resp;
5728
+ }
5729
+
5730
+ // ../../packages/sdk/dist/surfaces/index.js
5731
+ var RPC_API_SURFACE = [
5732
+ { name: "ethGetBalance", rpcMethod: "eth_getBalance", family: "evm", gateway: "network" },
5733
+ { name: "ethGetBlockByNumber", rpcMethod: "eth_getBlockByNumber", family: "evm", gateway: "network" },
5734
+ { name: "ethGetBlockByHash", rpcMethod: "eth_getBlockByHash", family: "evm", gateway: "network" },
5735
+ { name: "ethGetTransactionByHash", rpcMethod: "eth_getTransactionByHash", family: "evm", gateway: "network" },
5736
+ { name: "ethGetTransactionReceipt", rpcMethod: "eth_getTransactionReceipt", family: "evm", gateway: "network" },
5737
+ { name: "ethGetTransactionCount", rpcMethod: "eth_getTransactionCount", family: "evm", gateway: "network" },
5738
+ { name: "ethBlockNumber", rpcMethod: "eth_blockNumber", family: "evm", gateway: "network" },
5739
+ { name: "ethGasPrice", rpcMethod: "eth_gasPrice", family: "evm", gateway: "network" },
5740
+ { name: "ethEstimateGas", rpcMethod: "eth_estimateGas", family: "evm", gateway: "network" },
5741
+ { name: "ethGetCode", rpcMethod: "eth_getCode", family: "evm", gateway: "network" },
5742
+ { name: "ethGetStorageAt", rpcMethod: "eth_getStorageAt", family: "evm", gateway: "network" },
5743
+ { name: "ethGetLogs", rpcMethod: "eth_getLogs", family: "evm", gateway: "network" },
5744
+ { name: "ethChainId", rpcMethod: "eth_chainId", family: "evm", gateway: "network" },
5745
+ { name: "ethFeeHistory", rpcMethod: "eth_feeHistory", family: "evm", gateway: "network" },
5746
+ { name: "ethMaxPriorityFeePerGas", rpcMethod: "eth_maxPriorityFeePerGas", family: "evm", gateway: "network" },
5747
+ { name: "netVersion", rpcMethod: "net_version", family: "evm", gateway: "network" },
5748
+ { name: "web3ClientVersion", rpcMethod: "web3_clientVersion", family: "evm", gateway: "network" },
5749
+ { name: "ethGetBlockTransactionCountByHash", rpcMethod: "eth_getBlockTransactionCountByHash", family: "evm", gateway: "network" },
5750
+ { name: "ethGetBlockTransactionCountByNumber", rpcMethod: "eth_getBlockTransactionCountByNumber", family: "evm", gateway: "network" },
5751
+ { name: "ethGetTransactionByBlockHashAndIndex", rpcMethod: "eth_getTransactionByBlockHashAndIndex", family: "evm", gateway: "network" },
5752
+ { name: "ethGetTransactionByBlockNumberAndIndex", rpcMethod: "eth_getTransactionByBlockNumberAndIndex", family: "evm", gateway: "network" },
5753
+ { name: "ethSyncing", rpcMethod: "eth_syncing", family: "evm", gateway: "network" },
5754
+ { name: "ethCallBundle", rpcMethod: "eth_callBundle", family: "evm", gateway: "network" },
5755
+ { name: "ethCallMany", rpcMethod: "eth_callMany", family: "evm", gateway: "network" },
5756
+ { name: "netListening", rpcMethod: "net_listening", family: "evm", gateway: "network" },
5757
+ { name: "web3Sha3", rpcMethod: "web3_sha3", family: "evm", gateway: "network" },
5758
+ { name: "getTokenBalances", rpcMethod: "alchemy_getTokenBalances", family: "evm", gateway: "network" },
5759
+ { name: "getTokenMetadata", rpcMethod: "alchemy_getTokenMetadata", family: "evm", gateway: "network" },
5760
+ { name: "getTokenAllowance", rpcMethod: "alchemy_getTokenAllowance", family: "evm", gateway: "network" },
5761
+ { name: "getAssetTransfers", rpcMethod: "alchemy_getAssetTransfers", family: "evm", gateway: "network" },
5762
+ { name: "getTransactionReceipts", rpcMethod: "alchemy_getTransactionReceipts", family: "evm", gateway: "network" },
5763
+ { name: "simulateAssetChanges", rpcMethod: "alchemy_simulateAssetChanges", family: "evm", gateway: "network" },
5764
+ { name: "simulateExecution", rpcMethod: "alchemy_simulateExecution", family: "evm", gateway: "network" },
5765
+ { name: "traceCall", rpcMethod: "trace_call", family: "evm", gateway: "network" },
5766
+ { name: "traceTransaction", rpcMethod: "trace_transaction", family: "evm", gateway: "network" },
5767
+ { name: "traceBlock", rpcMethod: "trace_block", family: "evm", gateway: "network" },
5768
+ { name: "debugTraceTransaction", rpcMethod: "debug_traceTransaction", family: "evm", gateway: "network" },
5769
+ { name: "debugTraceCall", rpcMethod: "debug_traceCall", family: "evm", gateway: "network" },
5770
+ { name: "estimateUserOperationGas", rpcMethod: "estimateUserOperationGas", family: "evm", gateway: "network" },
5771
+ { name: "getUserOperationReceipt", rpcMethod: "getUserOperationReceipt", family: "evm", gateway: "network" },
5772
+ { name: "getUserOperationByHash", rpcMethod: "getUserOperationByHash", family: "evm", gateway: "network" },
5773
+ { name: "supportedEntryPoints", rpcMethod: "supportedEntryPoints", family: "evm", gateway: "network" },
5774
+ { name: "solana_getAsset", rpcMethod: "getAsset", family: "solana", gateway: "network" },
5775
+ { name: "solana_getAssetsByOwner", rpcMethod: "getAssetsByOwner", family: "solana", gateway: "network" },
5776
+ { name: "solana_searchAssets", rpcMethod: "searchAssets", family: "solana", gateway: "network" },
5777
+ { name: "getTokenAccounts", rpcMethod: "getTokenAccounts", family: "solana", gateway: "network" },
5778
+ { name: "solana_getAssets", rpcMethod: "getAssets", family: "solana", gateway: "network" },
5779
+ { name: "solana_getAssetProof", rpcMethod: "getAssetProof", family: "solana", gateway: "network" },
5780
+ { name: "solana_getAssetsByAuthority", rpcMethod: "getAssetsByAuthority", family: "solana", gateway: "network" },
5781
+ { name: "solana_getAssetsByGroup", rpcMethod: "getAssetsByGroup", family: "solana", gateway: "network" },
5782
+ { name: "solana_getAssetsByCreator", rpcMethod: "getAssetsByCreator", family: "solana", gateway: "network" },
5783
+ { name: "solana_getAssetSignatures", rpcMethod: "getAssetSignatures", family: "solana", gateway: "network" },
5784
+ { name: "getNftEditions", rpcMethod: "getNftEditions", family: "solana", gateway: "network" },
5785
+ { name: "simulateAssetChangesBundle", rpcMethod: "alchemy_simulateAssetChangesBundle", family: "evm", gateway: "network" },
5786
+ { name: "simulateExecutionBundle", rpcMethod: "alchemy_simulateExecutionBundle", family: "evm", gateway: "network" },
5787
+ { name: "simulateUserOperationAssetChanges", rpcMethod: "alchemy_simulateUserOperationAssetChanges", family: "evm", gateway: "network" },
5788
+ { name: "traceFilter", rpcMethod: "trace_filter", family: "evm", gateway: "network" },
5789
+ { name: "traceReplayTransaction", rpcMethod: "trace_replayTransaction", family: "evm", gateway: "network" },
5790
+ { name: "traceReplayBlockTransactions", rpcMethod: "trace_replayBlockTransactions", family: "evm", gateway: "network" },
5791
+ { name: "debugTraceBlockByNumber", rpcMethod: "debug_traceBlockByNumber", family: "evm", gateway: "network" },
5792
+ { name: "debugTraceBlockByHash", rpcMethod: "debug_traceBlockByHash", family: "evm", gateway: "network" },
5793
+ { name: "debugGetRawBlock", rpcMethod: "debug_getRawBlock", family: "evm", gateway: "network" },
5794
+ { name: "debugGetRawReceipts", rpcMethod: "debug_getRawReceipts", family: "evm", gateway: "network" },
5795
+ { name: "requestGasAndPaymasterAndData", rpcMethod: "alchemy_requestGasAndPaymasterAndData", family: "evm", gateway: "network" },
5796
+ { name: "requestPaymasterAndData", rpcMethod: "alchemy_requestPaymasterAndData", family: "evm", gateway: "network" },
5797
+ { name: "ethCall", rpcMethod: "eth_call", family: "evm", gateway: "network" },
5798
+ { name: "ethGetBlockReceipts", rpcMethod: "eth_getBlockReceipts", family: "evm", gateway: "network" },
5799
+ { name: "ethGetProof", rpcMethod: "eth_getProof", family: "evm", gateway: "network" },
5800
+ { name: "ethCreateAccessList", rpcMethod: "eth_createAccessList", family: "evm", gateway: "network" },
5801
+ { name: "ethBlobBaseFee", rpcMethod: "eth_blobBaseFee", family: "evm", gateway: "network" },
5802
+ { name: "rundlerMaxPriorityFeePerGas", rpcMethod: "rundler_maxPriorityFeePerGas", family: "evm", gateway: "network" },
5803
+ { name: "solana_getBalance", rpcMethod: "getBalance", family: "solana", gateway: "network" },
5804
+ { name: "solana_getAccountInfo", rpcMethod: "getAccountInfo", family: "solana", gateway: "network" },
5805
+ { name: "solana_getMultipleAccounts", rpcMethod: "getMultipleAccounts", family: "solana", gateway: "network" },
5806
+ { name: "solana_getTransaction", rpcMethod: "getTransaction", family: "solana", gateway: "network" },
5807
+ { name: "solana_getSignaturesForAddress", rpcMethod: "getSignaturesForAddress", family: "solana", gateway: "network" },
5808
+ { name: "solana_getSignatureStatuses", rpcMethod: "getSignatureStatuses", family: "solana", gateway: "network" },
5809
+ { name: "solana_simulateTransaction", rpcMethod: "simulateTransaction", family: "solana", gateway: "network" },
5810
+ { name: "solana_getTokenAccountBalance", rpcMethod: "getTokenAccountBalance", family: "solana", gateway: "network" },
5811
+ { name: "solana_getTokenAccountsByOwner", rpcMethod: "getTokenAccountsByOwner", family: "solana", gateway: "network" },
5812
+ { name: "solana_getTokenAccountsByDelegate", rpcMethod: "getTokenAccountsByDelegate", family: "solana", gateway: "network" },
5813
+ { name: "solana_getTokenSupply", rpcMethod: "getTokenSupply", family: "solana", gateway: "network" },
5814
+ { name: "solana_getTokenLargestAccounts", rpcMethod: "getTokenLargestAccounts", family: "solana", gateway: "network" },
5815
+ { name: "solana_getBlock", rpcMethod: "getBlock", family: "solana", gateway: "network" },
5816
+ { name: "solana_getBlockHeight", rpcMethod: "getBlockHeight", family: "solana", gateway: "network" },
5817
+ { name: "solana_getBlockTime", rpcMethod: "getBlockTime", family: "solana", gateway: "network" },
5818
+ { name: "solana_getBlocks", rpcMethod: "getBlocks", family: "solana", gateway: "network" },
5819
+ { name: "solana_getSlot", rpcMethod: "getSlot", family: "solana", gateway: "network" },
5820
+ { name: "solana_getLatestBlockhash", rpcMethod: "getLatestBlockhash", family: "solana", gateway: "network" },
5821
+ { name: "solana_isBlockhashValid", rpcMethod: "isBlockhashValid", family: "solana", gateway: "network" },
5822
+ { name: "solana_getProgramAccounts", rpcMethod: "getProgramAccounts", family: "solana", gateway: "network" },
5823
+ { name: "solana_getEpochInfo", rpcMethod: "getEpochInfo", family: "solana", gateway: "network" },
5824
+ { name: "solana_getSupply", rpcMethod: "getSupply", family: "solana", gateway: "network" },
5825
+ { name: "solana_getVersion", rpcMethod: "getVersion", family: "solana", gateway: "network" },
5826
+ { name: "solana_getTransactionCount", rpcMethod: "getTransactionCount", family: "solana", gateway: "network" },
5827
+ { name: "solana_getInflationRate", rpcMethod: "getInflationRate", family: "solana", gateway: "network" },
5828
+ { name: "solana_getInflationReward", rpcMethod: "getInflationReward", family: "solana", gateway: "network" },
5829
+ { name: "solana_getVoteAccounts", rpcMethod: "getVoteAccounts", family: "solana", gateway: "network" },
5830
+ { name: "solana_getLargestAccounts", rpcMethod: "getLargestAccounts", family: "solana", gateway: "network" },
5831
+ { name: "solana_getFeeForMessage", rpcMethod: "getFeeForMessage", family: "solana", gateway: "network" },
5832
+ { name: "solana_getRecentPrioritizationFees", rpcMethod: "getRecentPrioritizationFees", family: "solana", gateway: "network" },
5833
+ { name: "solana_getMinimumBalanceForRentExemption", rpcMethod: "getMinimumBalanceForRentExemption", family: "solana", gateway: "network" },
5834
+ { name: "solana_getPriorityFeeEstimate", rpcMethod: "getPriorityFeeEstimate", family: "solana", gateway: "network" },
5835
+ { name: "solana_getClusterNodes", rpcMethod: "getClusterNodes", family: "solana", gateway: "network" },
5836
+ { name: "solana_getLeaderSchedule", rpcMethod: "getLeaderSchedule", family: "solana", gateway: "network" },
5837
+ { name: "solana_getMaxRetransmitSlot", rpcMethod: "getMaxRetransmitSlot", family: "solana", gateway: "network" },
5838
+ { name: "solana_getMaxShredInsertSlot", rpcMethod: "getMaxShredInsertSlot", family: "solana", gateway: "network" },
5839
+ { name: "solana_getRecentPerformanceSamples", rpcMethod: "getRecentPerformanceSamples", family: "solana", gateway: "network" },
5840
+ { name: "solana_getFirstAvailableBlock", rpcMethod: "getFirstAvailableBlock", family: "solana", gateway: "network" },
5841
+ { name: "solana_getGenesisHash", rpcMethod: "getGenesisHash", family: "solana", gateway: "network" },
5842
+ { name: "solana_getHighestSnapshotSlot", rpcMethod: "getHighestSnapshotSlot", family: "solana", gateway: "network" },
5843
+ { name: "solana_getIdentity", rpcMethod: "getIdentity", family: "solana", gateway: "network" },
5844
+ { name: "solana_getInflationGovernor", rpcMethod: "getInflationGovernor", family: "solana", gateway: "network" },
5845
+ { name: "solana_minimumLedgerSlot", rpcMethod: "minimumLedgerSlot", family: "solana", gateway: "network" },
5846
+ { name: "solana_requestAirdrop", rpcMethod: "requestAirdrop", family: "solana", gateway: "network" },
5847
+ { name: "solana_getBlockCommitment", rpcMethod: "getBlockCommitment", family: "solana", gateway: "network" },
5848
+ { name: "solana_getBlockProduction", rpcMethod: "getBlockProduction", family: "solana", gateway: "network" },
5849
+ { name: "solana_getSlotLeader", rpcMethod: "getSlotLeader", family: "solana", gateway: "network" },
5850
+ { name: "solana_getSlotLeaders", rpcMethod: "getSlotLeaders", family: "solana", gateway: "network" },
5851
+ { name: "solana_getEpochSchedule", rpcMethod: "getEpochSchedule", family: "solana", gateway: "network" },
5852
+ { name: "solana_getBlocksWithLimit", rpcMethod: "getBlocksWithLimit", family: "solana", gateway: "network" },
5853
+ { name: "solana_getStakeActivation", rpcMethod: "getStakeActivation", family: "solana", gateway: "network" },
5854
+ { name: "solana_simulateBundle", rpcMethod: "simulateBundle", family: "solana", gateway: "network" }
5855
+ ];
5856
+ var DATA_API_SURFACE = [
5857
+ { name: "getNFTsForOwner", service: "nft", sdkMethod: "getNFTsForOwner", transport: "get", input: "query", requiresNetwork: true },
5858
+ { name: "getNFTsForContract", service: "nft", sdkMethod: "getNFTsForContract", transport: "get", input: "query", requiresNetwork: true },
5859
+ { name: "getNFTMetadata", service: "nft", sdkMethod: "getNFTMetadata", transport: "get", input: "query", requiresNetwork: true },
5860
+ { name: "getNFTMetadataBatch", service: "nft", sdkMethod: "getNFTMetadataBatch", transport: "post", input: "body", requiresNetwork: true },
5861
+ { name: "getContractMetadata", service: "nft", sdkMethod: "getContractMetadata", transport: "get", input: "query", requiresNetwork: true },
5862
+ { name: "getOwnersForNFT", service: "nft", sdkMethod: "getOwnersForNFT", transport: "get", input: "query", requiresNetwork: true },
5863
+ { name: "getOwnersForContract", service: "nft", sdkMethod: "getOwnersForContract", transport: "get", input: "query", requiresNetwork: true },
5864
+ { name: "getFloorPrice", service: "nft", sdkMethod: "getFloorPrice", transport: "get", input: "query", requiresNetwork: true },
5865
+ { name: "isSpamContract", service: "nft", sdkMethod: "isSpamContract", transport: "get", input: "query", requiresNetwork: true },
5866
+ { name: "searchContractMetadata", service: "nft", sdkMethod: "searchContractMetadata", transport: "get", input: "query", requiresNetwork: true },
5867
+ { name: "getNFTSales", service: "nft", sdkMethod: "getNFTSales", transport: "get", input: "query", requiresNetwork: true },
5868
+ { name: "getContractsForOwner", service: "nft", sdkMethod: "getContractsForOwner", transport: "get", input: "query", requiresNetwork: true },
5869
+ { name: "getNFTsForCollection", service: "nft", sdkMethod: "getNFTsForCollection", transport: "get", input: "query", requiresNetwork: true },
5870
+ { name: "getCollectionMetadata", service: "nft", sdkMethod: "getCollectionMetadata", transport: "get", input: "query", requiresNetwork: true },
5871
+ { name: "getContractMetadataBatch", service: "nft", sdkMethod: "getContractMetadataBatch", transport: "post", input: "body", requiresNetwork: true },
5872
+ { name: "getSpamContracts", service: "nft", sdkMethod: "getSpamContracts", transport: "get", input: "none", requiresNetwork: true },
5873
+ { name: "isAirdropNFT", service: "nft", sdkMethod: "isAirdropNFT", transport: "get", input: "query", requiresNetwork: true },
5874
+ { name: "summarizeNFTAttributes", service: "nft", sdkMethod: "summarizeNFTAttributes", transport: "get", input: "query", requiresNetwork: true },
5875
+ { name: "isHolderOfContract", service: "nft", sdkMethod: "isHolderOfContract", transport: "get", input: "query", requiresNetwork: true },
5876
+ { name: "computeRarity", service: "nft", sdkMethod: "computeRarity", transport: "get", input: "query", requiresNetwork: true },
5877
+ { name: "getCollectionsForOwner", service: "nft", sdkMethod: "getCollectionsForOwner", transport: "get", input: "query", requiresNetwork: true },
5878
+ { name: "getTokenPricesBySymbol", service: "prices", sdkMethod: "getTokenPricesBySymbol", transport: "get", input: "query", requiresNetwork: false },
5879
+ { name: "getTokenPricesByAddress", service: "prices", sdkMethod: "getTokenPricesByAddress", transport: "post", input: "body", requiresNetwork: false },
5880
+ { name: "getHistoricalTokenPrices", service: "prices", sdkMethod: "getHistoricalTokenPrices", transport: "post", input: "body", requiresNetwork: false },
5881
+ { name: "getTokensByAddress", service: "portfolio", sdkMethod: "getTokensByAddress", transport: "post", input: "body", requiresNetwork: false },
5882
+ { name: "getTokenBalancesByAddress", service: "portfolio", sdkMethod: "getTokenBalancesByAddress", transport: "post", input: "body", requiresNetwork: false },
5883
+ { name: "getNFTsByAddress", service: "portfolio", sdkMethod: "getNFTsByAddress", transport: "post", input: "body", requiresNetwork: false },
5884
+ { name: "getNFTContractsByAddress", service: "portfolio", sdkMethod: "getNFTContractsByAddress", transport: "post", input: "body", requiresNetwork: false }
5885
+ ];
5886
+ var RPC_API_TOOL_NAMES = RPC_API_SURFACE.map((method) => method.name);
5887
+ var DATA_API_TOOL_NAMES = DATA_API_SURFACE.map((method) => method.name);
5888
+
5889
+ // src/commands/surface-parity.ts
5890
+ function registerEvmRpcSurfaceCommands(root, rpc) {
5891
+ for (const method of RPC_API_SURFACE.filter((entry) => entry.family === "evm")) {
5892
+ registerRpcSurfaceCommand({ root, parent: rpc, method });
5893
+ }
5894
+ }
5895
+ function registerSolanaRpcSurfaceCommands(root, solana) {
5896
+ for (const method of RPC_API_SURFACE.filter((entry) => entry.family === "solana")) {
5897
+ registerRpcSurfaceCommand({ root, parent: solana, method });
5898
+ }
5899
+ }
5900
+ function registerDataSurfaceCommands(root, data) {
5901
+ for (const method of DATA_API_SURFACE) {
5902
+ const command = data.command(method.name).description(`Call ${method.name}`);
5903
+ if (method.input === "query") {
5904
+ command.option("--query <json>", "Query parameters as a JSON object", "{}");
5905
+ } else if (method.input === "body") {
5906
+ command.option("--body <json>", "Request body as a JSON object", "{}");
5907
+ }
5908
+ command.action(async (opts) => {
5909
+ try {
5910
+ const apiKey = resolveAPIKey(root);
5911
+ if (!apiKey) {
5912
+ throw errAuthRequired();
5913
+ }
5914
+ const client = createAlchemyDataClient(apiKey, { breadcrumb: "alchemy-cli" });
5915
+ const result = await withSpinner(
5916
+ `Calling ${method.name}...`,
5917
+ `Called ${method.name}`,
5918
+ () => callDataMethod(client, method, root, opts)
5919
+ );
5920
+ printSyntaxJSON(result);
5921
+ } catch (err) {
5922
+ exitWithError(mapDataError(err));
5923
+ }
5924
+ });
5925
+ }
5926
+ }
5927
+ function registerRpcSurfaceCommand({ root, parent, method }) {
5928
+ parent.command(method.name).description(`Call ${method.rpcMethod}`).option("--params <json>", "JSON-RPC params as an array or object", "[]").action(async (opts) => {
5929
+ try {
5930
+ const params = parseRpcParams(opts.params);
5931
+ let result;
5932
+ if (method.gateway === "global") {
5933
+ const apiKey = resolveAPIKey(root);
5934
+ if (!apiKey) {
5935
+ throw errAuthRequired();
5936
+ }
5937
+ if (!Array.isArray(params)) {
5938
+ throw errInvalidArgs("--params must be a JSON array for global RPC methods.");
5939
+ }
5940
+ result = await withSpinner(
5941
+ `Calling ${method.name}...`,
5942
+ `Called ${method.name}`,
5943
+ () => globalRpcCall(apiKey, method.rpcMethod, params, {
5944
+ breadcrumb: "alchemy-cli",
5945
+ ...timeout && { timeoutMs: timeout }
5946
+ })
5947
+ );
5948
+ } else {
5949
+ const client = method.family === "solana" ? clientFromFlags(root, { forceNetwork: resolveSolanaNetwork(root) }) : clientFromFlags(root);
5950
+ result = await withSpinner(
5951
+ `Calling ${method.name}...`,
5952
+ `Called ${method.name}`,
5953
+ () => client.call(method.rpcMethod, params)
5954
+ );
5955
+ }
5956
+ printSyntaxJSON(result);
5957
+ } catch (err) {
5958
+ exitWithError(mapRpcError(err));
5959
+ }
5960
+ });
5961
+ }
5962
+ function parseRpcParams(input) {
5963
+ const parsed = parseRequiredJSON(input, "--params");
5964
+ if (Array.isArray(parsed)) {
5965
+ return parsed;
5966
+ }
5967
+ if (isPlainObject(parsed)) {
5968
+ return parsed;
5969
+ }
5970
+ throw errInvalidArgs("--params must be a JSON array or object.");
5971
+ }
5972
+ async function callDataMethod(client, method, root, opts) {
5973
+ if (method.service === "nft") {
5974
+ const fn2 = client.nft[method.sdkMethod];
5975
+ const network = resolveNetwork(root);
5976
+ if (method.input === "none") {
5977
+ return await fn2.call(client.nft, network);
5978
+ }
5979
+ if (method.input === "body") {
5980
+ return await fn2.call(client.nft, network, parseDataObject(opts.body ?? "{}", "--body"));
5981
+ }
5982
+ return await fn2.call(client.nft, network, normalizeQuery(parseDataObject(opts.query ?? "{}", "--query")));
5983
+ }
5984
+ if (method.service === "prices") {
5985
+ const fn2 = client.prices[method.sdkMethod];
5986
+ if (method.input === "body") {
5987
+ return await fn2.call(client.prices, parseDataObject(opts.body ?? "{}", "--body"));
5988
+ }
5989
+ return await fn2.call(client.prices, parseDataObject(opts.query ?? "{}", "--query"));
5990
+ }
5991
+ const fn = client.portfolio[method.sdkMethod];
5992
+ return await fn.call(client.portfolio, parseDataObject(opts.body ?? "{}", "--body"));
5993
+ }
5994
+ function parseDataObject(input, label) {
5995
+ const parsed = parseRequiredJSON(input, label);
5996
+ if (isPlainObject(parsed)) {
5997
+ return parsed;
5998
+ }
5999
+ throw errInvalidArgs(`${label} must be a JSON object.`);
6000
+ }
6001
+ function normalizeQuery(input) {
6002
+ const out = {};
6003
+ for (const [key, value] of Object.entries(input)) {
6004
+ if (value === void 0 || value === null) {
6005
+ continue;
6006
+ }
6007
+ if (Array.isArray(value)) {
6008
+ out[key] = value.map((item) => String(item));
6009
+ } else {
6010
+ out[key] = String(value);
6011
+ }
6012
+ }
6013
+ return out;
6014
+ }
6015
+ function isPlainObject(value) {
6016
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
6017
+ }
6018
+ function mapRpcError(err) {
6019
+ if (!(err instanceof RpcApiError)) {
6020
+ return err;
6021
+ }
6022
+ if (err.status === 429) {
6023
+ return errRateLimited();
6024
+ }
6025
+ if (err.status === 401 || err.status === 403) {
6026
+ return errInvalidAPIKey(err.message);
6027
+ }
6028
+ if (err.status !== void 0) {
6029
+ return errNetwork(`HTTP ${err.status}: ${err.message}`);
6030
+ }
6031
+ return errRPC(err.code, err.message);
6032
+ }
6033
+ function mapDataError(err) {
6034
+ if (!(err instanceof DataApiError)) {
6035
+ return err;
6036
+ }
6037
+ if (err.status === 429) {
6038
+ return errRateLimited();
6039
+ }
6040
+ if (err.status === 401 || err.status === 403) {
6041
+ return errInvalidAPIKey(err.message);
6042
+ }
6043
+ return errNetwork(`HTTP ${err.status}: ${err.message}`);
6044
+ }
6045
+
5105
6046
  // src/commands/solana.ts
5106
6047
  function registerReservedSolanaCommand(args) {
5107
6048
  args.cmd.command(args.signature).description(args.description).action(() => {
@@ -5159,6 +6100,7 @@ function registerSolana(program2) {
5159
6100
  registerSolanaProgram(cmd);
5160
6101
  registerSolanaDelegate(cmd);
5161
6102
  registerStatus(cmd, { networkMode: "solana" });
6103
+ registerSolanaRpcSurfaceCommands(program2, cmd);
5162
6104
  registerReservedSolanaCommands(cmd);
5163
6105
  }
5164
6106
 
@@ -5695,8 +6637,8 @@ function registrySymbolSuggestions(network) {
5695
6637
  }
5696
6638
 
5697
6639
  // src/commands/approve.ts
5698
- function isNativeToken(address2) {
5699
- return address2.toLowerCase() === NATIVE_TOKEN_ADDRESS.toLowerCase();
6640
+ function isNativeToken(address3) {
6641
+ return address3.toLowerCase() === NATIVE_TOKEN_ADDRESS.toLowerCase();
5700
6642
  }
5701
6643
  function buildApprovalRequest(opts, tokenMeta) {
5702
6644
  validateApprovalMode(opts);
@@ -6368,18 +7310,18 @@ async function performContractCall(program2, addressArg, functionArg, opts) {
6368
7310
  // src/commands/balance.ts
6369
7311
  async function fetchBalance(program2, addressInput, blockParam) {
6370
7312
  const client = clientFromFlags(program2);
6371
- const address2 = await resolveAddress(addressInput, client);
7313
+ const address3 = await resolveAddress(addressInput, client);
6372
7314
  const result = await withSpinner(
6373
7315
  "Fetching balance\u2026",
6374
7316
  "Balance fetched",
6375
- () => client.call("eth_getBalance", [address2, blockParam])
7317
+ () => client.call("eth_getBalance", [address3, blockParam])
6376
7318
  );
6377
7319
  const wei = BigInt(result);
6378
7320
  const network = resolveNetwork(program2);
6379
7321
  const symbol = nativeTokenSymbol(network);
6380
7322
  if (isJSONMode()) {
6381
7323
  printJSON({
6382
- address: address2,
7324
+ address: address3,
6383
7325
  wei: wei.toString(),
6384
7326
  balance: weiToEth(wei),
6385
7327
  symbol,
@@ -6387,7 +7329,7 @@ async function fetchBalance(program2, addressInput, blockParam) {
6387
7329
  });
6388
7330
  } else {
6389
7331
  printKeyValue([
6390
- ["Address", address2],
7332
+ ["Address", address3],
6391
7333
  ["Balance", green(`${weiToEth(wei)} ${symbol}`)],
6392
7334
  ["Network", network]
6393
7335
  ]);
@@ -6395,7 +7337,7 @@ async function fetchBalance(program2, addressInput, blockParam) {
6395
7337
  console.log("");
6396
7338
  printJSON({
6397
7339
  rpcMethod: "eth_getBalance",
6398
- rpcParams: [address2, blockParam],
7340
+ rpcParams: [address3, blockParam],
6399
7341
  rpcResult: result
6400
7342
  });
6401
7343
  }
@@ -6480,9 +7422,9 @@ Examples:
6480
7422
  try {
6481
7423
  const addressInput = addressArg ?? await readStdinArg("address");
6482
7424
  const client = clientFromFlags(program2);
6483
- const address2 = await resolveAddress(addressInput, client);
7425
+ const address3 = await resolveAddress(addressInput, client);
6484
7426
  const params = {
6485
- owner: address2,
7427
+ owner: address3,
6486
7428
  withMetadata: "true"
6487
7429
  };
6488
7430
  if (opts.limit) params.pageSize = String(opts.limit);
@@ -6516,7 +7458,7 @@ Examples:
6516
7458
  break;
6517
7459
  }
6518
7460
  const nextParams = {
6519
- owner: address2,
7461
+ owner: address3,
6520
7462
  withMetadata: "true",
6521
7463
  pageKey
6522
7464
  };
@@ -6558,15 +7500,15 @@ Examples:
6558
7500
  exitWithError(err);
6559
7501
  }
6560
7502
  });
6561
- cmd.command("contract <address>").description("Get NFT contract metadata").action(async (address2) => {
7503
+ cmd.command("contract <address>").description("Get NFT contract metadata").action(async (address3) => {
6562
7504
  try {
6563
- validateAddress(address2);
7505
+ validateAddress(address3);
6564
7506
  const client = clientFromFlags(program2);
6565
7507
  const result = await withSpinner(
6566
7508
  "Fetching contract metadata\u2026",
6567
7509
  "Contract metadata fetched",
6568
7510
  () => client.callEnhanced("getContractMetadata", {
6569
- contractAddress: address2
7511
+ contractAddress: address3
6570
7512
  })
6571
7513
  );
6572
7514
  if (isJSONMode()) printJSON(result);
@@ -6703,8 +7645,8 @@ Examples:
6703
7645
  try {
6704
7646
  const addressInput = addressArg ?? await readStdinArg("address");
6705
7647
  const client = clientFromFlags(program2);
6706
- const address2 = await resolveAddress(addressInput, client);
6707
- const params = [address2];
7648
+ const address3 = await resolveAddress(addressInput, client);
7649
+ const params = [address3];
6708
7650
  if (opts.pageKey) {
6709
7651
  params.push("erc20", { pageKey: opts.pageKey });
6710
7652
  }
@@ -6741,7 +7683,7 @@ Examples:
6741
7683
  }
6742
7684
  let totalShown = nonZero.length;
6743
7685
  printKeyValue([
6744
- ["Address", address2],
7686
+ ["Address", address3],
6745
7687
  ["Network", client.network],
6746
7688
  ["Tokens", String(totalShown)]
6747
7689
  ]);
@@ -6767,7 +7709,7 @@ Examples:
6767
7709
  const nextResult = await withSpinner(
6768
7710
  "Fetching next page\u2026",
6769
7711
  "Page fetched",
6770
- () => client.call("alchemy_getTokenBalances", [address2, "erc20", { pageKey }])
7712
+ () => client.call("alchemy_getTokenBalances", [address3, "erc20", { pageKey }])
6771
7713
  );
6772
7714
  if (isJSONMode()) {
6773
7715
  printJSON(nextResult);
@@ -6887,7 +7829,7 @@ Examples:
6887
7829
  ).action(async (addressArg, opts) => {
6888
7830
  try {
6889
7831
  const client = clientFromFlags(program2);
6890
- const address2 = addressArg ? await resolveAddress(addressArg, client) : void 0;
7832
+ const address3 = addressArg ? await resolveAddress(addressArg, client) : void 0;
6891
7833
  if (opts.fromAddress) opts.fromAddress = await resolveAddress(opts.fromAddress, client);
6892
7834
  if (opts.toAddress) opts.toAddress = await resolveAddress(opts.toAddress, client);
6893
7835
  const baseFilter = {
@@ -6903,8 +7845,8 @@ Examples:
6903
7845
  }
6904
7846
  if (opts.pageKey) baseFilter.pageKey = opts.pageKey;
6905
7847
  const filter = { ...baseFilter };
6906
- if (address2 && !opts.fromAddress && !opts.toAddress) {
6907
- filter.fromAddress = address2;
7848
+ if (address3 && !opts.fromAddress && !opts.toAddress) {
7849
+ filter.fromAddress = address3;
6908
7850
  } else {
6909
7851
  if (opts.fromAddress) filter.fromAddress = opts.fromAddress;
6910
7852
  if (opts.toAddress) filter.toAddress = opts.toAddress;
@@ -7110,6 +8052,7 @@ function registerData(program2) {
7110
8052
  registerTransfers(cmd);
7111
8053
  registerPrices(cmd);
7112
8054
  registerPortfolio(cmd);
8055
+ registerDataSurfaceCommands(program2, cmd);
7113
8056
  }
7114
8057
 
7115
8058
  // src/commands/debug.ts
@@ -7409,7 +8352,7 @@ Tip: use 'alchemy evm tx <hash>' for transaction details (value, block, nonce).
7409
8352
 
7410
8353
  // src/commands/rpc.ts
7411
8354
  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(
8355
+ 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
8356
  "after",
7414
8357
  `
7415
8358
  Examples:
@@ -7418,6 +8361,9 @@ Examples:
7418
8361
  alchemy evm rpc eth_getBlockByNumber "0x1" true`
7419
8362
  ).action(async (method, params) => {
7420
8363
  try {
8364
+ if (outputRpcHelp(cmd, method, params)) {
8365
+ return;
8366
+ }
7421
8367
  const client = clientFromFlags(program2);
7422
8368
  const parsed = params.map((p) => {
7423
8369
  try {
@@ -7437,6 +8383,24 @@ Examples:
7437
8383
  exitWithError(err);
7438
8384
  }
7439
8385
  });
8386
+ registerEvmRpcSurfaceCommands(program2, cmd);
8387
+ }
8388
+ function outputRpcHelp(cmd, method, params) {
8389
+ if (method !== "help") {
8390
+ return false;
8391
+ }
8392
+ const [topic] = params;
8393
+ if (!topic) {
8394
+ cmd.outputHelp();
8395
+ return true;
8396
+ }
8397
+ const subcommand = cmd.commands.find((command) => command.name() === topic);
8398
+ if (subcommand) {
8399
+ subcommand.outputHelp();
8400
+ return true;
8401
+ }
8402
+ cmd.outputHelp();
8403
+ return true;
7440
8404
  }
7441
8405
 
7442
8406
  // src/commands/send-evm.ts
@@ -7470,7 +8434,7 @@ Examples:
7470
8434
  dryRun: opts.dryRun
7471
8435
  });
7472
8436
  } catch (err) {
7473
- const { exitWithError: exitWithError2 } = await import("./errors-T6XE2I2L.js");
8437
+ const { exitWithError: exitWithError2 } = await import("./errors-YPNK3AVF.js");
7474
8438
  exitWithError2(err);
7475
8439
  }
7476
8440
  });
@@ -7644,14 +8608,14 @@ import {
7644
8608
  // src/lib/wallet-quote-client.ts
7645
8609
  import { createClient } from "viem";
7646
8610
  import { parseAccount } from "viem/accounts";
7647
- function buildWalletQuoteClient(program2, address2) {
8611
+ function buildWalletQuoteClient(program2, address3) {
7648
8612
  const apiKey = resolveAPIKey(program2);
7649
8613
  if (!apiKey) throw errAuthRequired();
7650
8614
  const cfg = load();
7651
8615
  const network = resolveNetwork(program2, cfg);
7652
8616
  const chain = networkToChain(network);
7653
8617
  const client = createClient({
7654
- account: parseAccount(address2),
8618
+ account: parseAccount(address3),
7655
8619
  transport: createAlchemyWalletTransport(apiKey),
7656
8620
  chain,
7657
8621
  name: "alchemyQuoteClient"
@@ -7663,7 +8627,7 @@ function buildWalletQuoteClient(program2, address2) {
7663
8627
  client,
7664
8628
  network,
7665
8629
  chain,
7666
- address: address2,
8630
+ address: address3,
7667
8631
  paymaster: void 0
7668
8632
  };
7669
8633
  }
@@ -7740,8 +8704,8 @@ function normalizeQuoteError(err, flow) {
7740
8704
 
7741
8705
  // src/commands/swap.ts
7742
8706
  var NATIVE_DECIMALS = 18;
7743
- function isNativeToken2(address2) {
7744
- return address2.toLowerCase() === NATIVE_TOKEN_ADDRESS.toLowerCase();
8707
+ function isNativeToken2(address3) {
8708
+ return address3.toLowerCase() === NATIVE_TOKEN_ADDRESS.toLowerCase();
7745
8709
  }
7746
8710
  function slippagePercentToBasisPoints(percent) {
7747
8711
  return BigInt(Math.round(percent * 100));
@@ -8433,8 +9397,8 @@ import {
8433
9397
  swapActions as swapActions2
8434
9398
  } from "@alchemy/wallet-apis/experimental";
8435
9399
  var NATIVE_DECIMALS2 = 18;
8436
- function isNativeToken3(address2) {
8437
- return address2.toLowerCase() === NATIVE_TOKEN_ADDRESS.toLowerCase();
9400
+ function isNativeToken3(address3) {
9401
+ return address3.toLowerCase() === NATIVE_TOKEN_ADDRESS.toLowerCase();
8438
9402
  }
8439
9403
  function slippagePercentToBasisPoints2(percent) {
8440
9404
  return BigInt(Math.round(percent * 100));
@@ -9387,7 +10351,7 @@ async function flushProcessOutput() {
9387
10351
  }
9388
10352
  program.name("alchemy").description(
9389
10353
  "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(
10354
+ ).version("0.10.0", "-v, --version", "display CLI version").option("--api-key <key>", "Alchemy API key (env: ALCHEMY_API_KEY)").option(
9391
10355
  "-n, --network <network>",
9392
10356
  "Target network (default: eth-mainnet) (env: ALCHEMY_NETWORK)"
9393
10357
  ).option("--x402", "Use x402 wallet-based gateway auth").option(
@@ -9574,11 +10538,11 @@ ${styledLine}`;
9574
10538
  "wallet"
9575
10539
  ];
9576
10540
  if (!skipAppPrompt.includes(cmdName) && isInteractiveAllowed(program) && !opts.apiKey && !process.env.ALCHEMY_API_KEY) {
9577
- const { resolveAuthToken: resolveAuthToken2 } = await import("./resolve-FQ66OWT7.js");
10541
+ const { resolveAuthToken: resolveAuthToken2 } = await import("./resolve-REZCFZZ7.js");
9578
10542
  const authToken = resolveAuthToken2(cfg);
9579
10543
  const hasApiKey = Boolean(cfg.api_key?.trim() || cfg.app?.apiKey);
9580
10544
  if (authToken && !hasApiKey) {
9581
- const { selectAppAfterAuth } = await import("./auth-6BBITIOZ.js");
10545
+ const { selectAppAfterAuth } = await import("./auth-23OYLRWN.js");
9582
10546
  console.log("");
9583
10547
  console.log(` No app selected. Please select an app to continue.`);
9584
10548
  await selectAppAfterAuth(authToken);
@@ -9613,7 +10577,7 @@ ${styledLine}`;
9613
10577
  if (isInteractiveAllowed(program)) {
9614
10578
  let latestForInteractiveStartup = null;
9615
10579
  if (shouldRunOnboarding(program, cfg)) {
9616
- const { runOnboarding } = await import("./onboarding-CW7XGRE4.js");
10580
+ const { runOnboarding } = await import("./onboarding-A7IOH2MX.js");
9617
10581
  const latest = getAvailableUpdateOnce();
9618
10582
  const completed = await runOnboarding(program, latest);
9619
10583
  updateShownDuringInteractiveStartup = Boolean(latest);
@@ -9627,7 +10591,7 @@ ${styledLine}`;
9627
10591
  latestForInteractiveStartup
9628
10592
  );
9629
10593
  }
9630
- const { startREPL } = await import("./interactive-IBR6RN74.js");
10594
+ const { startREPL } = await import("./interactive-D34T7RI6.js");
9631
10595
  program.exitOverride();
9632
10596
  program.configureOutput({
9633
10597
  writeErr: () => {