@alchemy/cli 0.7.4 → 0.8.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
@@ -1,27 +1,36 @@
1
1
  #!/usr/bin/env node
2
2
  if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
3
+ import {
4
+ createPolicyInteractive,
5
+ errNotLoggedInForPolicyLookup,
6
+ errSponsorshipNeedsPolicy,
7
+ selectOrCreatePolicy
8
+ } from "./chunk-5Y7UQ27V.js";
3
9
  import {
4
10
  registerAuth
5
- } from "./chunk-XSN4XA5Z.js";
11
+ } from "./chunk-EKS2THJU.js";
6
12
  import {
7
13
  openBrowser
8
- } from "./chunk-C5HNQOLB.js";
14
+ } from "./chunk-NGF46GZP.js";
9
15
  import {
10
16
  SETUP_CAPABILITY_LABELS,
11
17
  SETUP_CAPABILITY_ORDER,
12
18
  getSetupStatus,
13
19
  isSetupComplete,
14
20
  shouldRunOnboarding
15
- } from "./chunk-R4W44A6E.js";
21
+ } from "./chunk-GNOTKJF4.js";
16
22
  import {
17
23
  isInteractiveAllowed
18
- } from "./chunk-64A5W4M2.js";
24
+ } from "./chunk-L7VFXQSF.js";
19
25
  import {
20
26
  adminClientFromFlags,
21
27
  clearSession,
22
28
  clientFromFlags,
23
29
  createPendingSession,
30
+ fromAdminNetworkId,
31
+ gasManagerClientFromFlags,
24
32
  getRPCNetworks,
33
+ hasAuthLoginToken,
25
34
  isSessionValid,
26
35
  isSolanaNetwork,
27
36
  loadSession,
@@ -42,13 +51,14 @@ import {
42
51
  resolveWalletSession,
43
52
  resolveX402Client,
44
53
  saveSession,
54
+ toAdminNetworkId,
45
55
  updateSession
46
- } from "./chunk-K6V3R7SH.js";
56
+ } from "./chunk-JWLZAO7S.js";
47
57
  import {
48
58
  getAvailableUpdate,
49
59
  getUpdateStatus,
50
60
  printUpdateNotice
51
- } from "./chunk-N36ZNOVV.js";
61
+ } from "./chunk-76ZO4UJ4.js";
52
62
  import {
53
63
  bold,
54
64
  brand,
@@ -72,7 +82,7 @@ import {
72
82
  weiToEth,
73
83
  withSpinner,
74
84
  yellow
75
- } from "./chunk-5IL2PMZ6.js";
85
+ } from "./chunk-DGZYRBXR.js";
76
86
  import {
77
87
  KEY_MAP,
78
88
  configDir,
@@ -83,7 +93,7 @@ import {
83
93
  save,
84
94
  toMap,
85
95
  validKeys
86
- } from "./chunk-JUCUKTP3.js";
96
+ } from "./chunk-ROBA7SR7.js";
87
97
  import {
88
98
  CLIError,
89
99
  EXIT_CODES,
@@ -119,7 +129,7 @@ import {
119
129
  setFlags,
120
130
  setNoColor,
121
131
  verbose
122
- } from "./chunk-2BALTY22.js";
132
+ } from "./chunk-46LMXT54.js";
123
133
 
124
134
  // src/index.ts
125
135
  import { Command, Help } from "commander";
@@ -552,12 +562,39 @@ function registerConfig(program2) {
552
562
  exitWithError(err);
553
563
  }
554
564
  });
555
- setCmd.command("evm-gas-policy-id <id>").description("Set the EVM gas policy ID for sponsored transactions").action((id) => {
565
+ setCmd.command("evm-gas-policy-id [id]").description("Set the EVM gas policy ID for sponsored transactions (omit ID for interactive)").action(async (id) => {
556
566
  try {
557
- const cfg = load();
558
- save({ ...cfg, evm_gas_policy_id: id });
559
- printHuman(`${green("\u2713")} Set evm-gas-policy-id
567
+ if (id) {
568
+ const cfg = load();
569
+ save({ ...cfg, evm_gas_policy_id: id });
570
+ printHuman(`${green("\u2713")} Set evm-gas-policy-id
560
571
  `, { key: "evm-gas-policy-id", status: "set" });
572
+ return;
573
+ }
574
+ if (!isInteractiveAllowed(program2)) {
575
+ throw errInvalidArgs(
576
+ "Interactive policy selection requires an interactive terminal. Pass an ID: `alchemy config set evm-gas-policy-id <id>`."
577
+ );
578
+ }
579
+ const { selectOrCreatePolicy: selectOrCreatePolicy2 } = await import("./policy-prompt-7AUZOA7S.js");
580
+ const { resolveNetwork: resolveNetwork2 } = await import("./resolve-N3SX252M.js");
581
+ const network = resolveNetwork2(program2);
582
+ await selectOrCreatePolicy2({
583
+ flavor: "sponsorship",
584
+ network,
585
+ program: program2,
586
+ skipPersistPrompt: true
587
+ }).then((policyId) => {
588
+ if (!policyId) return;
589
+ const cfg = load();
590
+ save({ ...cfg, evm_gas_policy_id: policyId });
591
+ printHuman(`${green("\u2713")} Set evm-gas-policy-id
592
+ `, {
593
+ key: "evm-gas-policy-id",
594
+ value: policyId,
595
+ status: "set"
596
+ });
597
+ });
561
598
  } catch (err) {
562
599
  exitWithError(err);
563
600
  }
@@ -580,12 +617,39 @@ function registerConfig(program2) {
580
617
  exitWithError(err);
581
618
  }
582
619
  });
583
- setCmd.command("solana-fee-policy-id <id>").description("Set the Solana fee policy ID for sponsored transactions").action((id) => {
620
+ setCmd.command("solana-fee-policy-id [id]").description("Set the Solana fee policy ID for sponsored transactions (omit ID for interactive)").action(async (id) => {
584
621
  try {
585
- const cfg = load();
586
- save({ ...cfg, solana_fee_policy_id: id });
587
- printHuman(`${green("\u2713")} Set solana-fee-policy-id
622
+ if (id) {
623
+ const cfg = load();
624
+ save({ ...cfg, solana_fee_policy_id: id });
625
+ printHuman(`${green("\u2713")} Set solana-fee-policy-id
588
626
  `, { key: "solana-fee-policy-id", status: "set" });
627
+ return;
628
+ }
629
+ if (!isInteractiveAllowed(program2)) {
630
+ throw errInvalidArgs(
631
+ "Interactive policy selection requires an interactive terminal. Pass an ID: `alchemy config set solana-fee-policy-id <id>`."
632
+ );
633
+ }
634
+ const { selectOrCreatePolicy: selectOrCreatePolicy2 } = await import("./policy-prompt-7AUZOA7S.js");
635
+ const { resolveSolanaNetwork: resolveSolanaNetwork2 } = await import("./resolve-N3SX252M.js");
636
+ const network = resolveSolanaNetwork2(program2);
637
+ await selectOrCreatePolicy2({
638
+ flavor: "solana",
639
+ network,
640
+ program: program2,
641
+ skipPersistPrompt: true
642
+ }).then((policyId) => {
643
+ if (!policyId) return;
644
+ const cfg = load();
645
+ save({ ...cfg, solana_fee_policy_id: policyId });
646
+ printHuman(`${green("\u2713")} Set solana-fee-policy-id
647
+ `, {
648
+ key: "solana-fee-policy-id",
649
+ value: policyId,
650
+ status: "set"
651
+ });
652
+ });
589
653
  } catch (err) {
590
654
  exitWithError(err);
591
655
  }
@@ -626,7 +690,7 @@ function registerConfig(program2) {
626
690
  printJSON(toMap(cfg));
627
691
  return;
628
692
  }
629
- const { resolveAuthToken: resolveAuthToken2 } = await import("./resolve-WXT5ZCUK.js");
693
+ const { resolveAuthToken: resolveAuthToken2 } = await import("./resolve-N3SX252M.js");
630
694
  const validToken = resolveAuthToken2(cfg);
631
695
  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");
632
696
  const pairs = [
@@ -3192,15 +3256,27 @@ async function waitForSolanaConfirmation(client, signature, timeoutMs = 6e4, pol
3192
3256
  }
3193
3257
 
3194
3258
  // src/lib/solana-fees.ts
3195
- function resolveSolanaFeeSponsorship(program2) {
3259
+ async function resolveSolanaFeeSponsorship(program2) {
3196
3260
  const sponsored = resolveSolanaFeeSponsored(program2);
3197
- const feePolicyId = resolveSolanaFeePolicyId(program2);
3198
- if (sponsored && !feePolicyId) {
3199
- throw errInvalidArgs(
3200
- "Fee sponsorship requires a fee policy ID. Set one with --fee-policy-id or configure a Solana fee policy."
3201
- );
3261
+ const existing = resolveSolanaFeePolicyId(program2);
3262
+ if (!sponsored) return { sponsored, feePolicyId: existing };
3263
+ if (existing) return { sponsored, feePolicyId: existing };
3264
+ if (!isInteractiveAllowed(program2)) {
3265
+ throw errSponsorshipNeedsPolicy("solana");
3266
+ }
3267
+ if (!hasAuthLoginToken()) {
3268
+ throw errNotLoggedInForPolicyLookup();
3269
+ }
3270
+ const network = resolveSolanaNetwork(program2);
3271
+ const selected = await selectOrCreatePolicy({
3272
+ flavor: "solana",
3273
+ network,
3274
+ program: program2
3275
+ });
3276
+ if (!selected) {
3277
+ throw errSponsorshipNeedsPolicy("solana");
3202
3278
  }
3203
- return { sponsored, feePolicyId };
3279
+ return { sponsored, feePolicyId: selected };
3204
3280
  }
3205
3281
 
3206
3282
  // src/commands/solana-delegate.ts
@@ -3263,7 +3339,7 @@ async function performSolanaDelegateApprove(program2, opts) {
3263
3339
  const rawAmount = parseAmount(opts.amount, decimals);
3264
3340
  const { keyBytes, signer } = await resolveLocalSolanaDelegateSigner(program2, opts.signer);
3265
3341
  const network = resolveSolanaNetwork(program2);
3266
- const { sponsored, feePolicyId } = resolveSolanaFeeSponsorship(program2);
3342
+ const { sponsored, feePolicyId } = await resolveSolanaFeeSponsorship(program2);
3267
3343
  const client = clientFromFlags(program2, { forceNetwork: network });
3268
3344
  const instruction = buildSplTokenApproveCheckedInstruction({
3269
3345
  tokenAccount: solAddress(opts.tokenAccount),
@@ -3325,7 +3401,7 @@ async function performSolanaDelegateRevoke(program2, opts) {
3325
3401
  validateSolanaAddress(opts.tokenAccount);
3326
3402
  const { keyBytes, signer } = await resolveLocalSolanaDelegateSigner(program2, opts.signer);
3327
3403
  const network = resolveSolanaNetwork(program2);
3328
- const { sponsored, feePolicyId } = resolveSolanaFeeSponsorship(program2);
3404
+ const { sponsored, feePolicyId } = await resolveSolanaFeeSponsorship(program2);
3329
3405
  const client = clientFromFlags(program2, { forceNetwork: network });
3330
3406
  const instruction = buildSplTokenRevokeInstruction({
3331
3407
  tokenAccount: solAddress(opts.tokenAccount),
@@ -3601,7 +3677,7 @@ async function performSolanaSend(program2, toArg, amountArg, tokenAddress, opts
3601
3677
  const lamports = parseAmount(amountArg, SOL_DECIMALS);
3602
3678
  const signer = await createSolanaSignerFromKeyBytes(keyBytes);
3603
3679
  const instruction = buildSolTransferInstruction(signer, to, lamports);
3604
- const { sponsored, feePolicyId } = resolveSolanaFeeSponsorship(program2);
3680
+ const { sponsored, feePolicyId } = await resolveSolanaFeeSponsorship(program2);
3605
3681
  const client = clientFromFlags(program2, { forceNetwork: network });
3606
3682
  const result = await withSpinner(
3607
3683
  "Sending transaction\u2026",
@@ -3998,6 +4074,28 @@ function createAlchemyWalletTransport(apiKey) {
3998
4074
  }
3999
4075
 
4000
4076
  // src/lib/smart-wallet.ts
4077
+ async function ensureGasPolicyResolved(program2) {
4078
+ const cfg = load();
4079
+ if (!resolveGasSponsored(program2, cfg)) return void 0;
4080
+ const existing = resolveGasPolicyId(program2, cfg);
4081
+ if (existing) return existing;
4082
+ if (!isInteractiveAllowed(program2)) {
4083
+ throw errSponsorshipNeedsPolicy("sponsorship");
4084
+ }
4085
+ if (!hasAuthLoginToken(cfg)) {
4086
+ throw errNotLoggedInForPolicyLookup();
4087
+ }
4088
+ const network = resolveNetwork(program2, cfg);
4089
+ const policyId = await selectOrCreatePolicy({
4090
+ flavor: "sponsorship",
4091
+ network,
4092
+ program: program2
4093
+ });
4094
+ if (!policyId) {
4095
+ throw errSponsorshipNeedsPolicy("sponsorship");
4096
+ }
4097
+ return policyId;
4098
+ }
4001
4099
  function normalizeKey(key) {
4002
4100
  const trimmed = key.trim();
4003
4101
  return trimmed.startsWith("0x") ? trimmed : `0x${trimmed}`;
@@ -4045,7 +4143,7 @@ function buildWalletClient(program2, options = {}) {
4045
4143
  const network = resolveNetwork(program2, cfg);
4046
4144
  const chain = networkToChain(network);
4047
4145
  const gasSponsored = resolveGasSponsored(program2, cfg);
4048
- const gasPolicyId = resolveGasPolicyId(program2, cfg);
4146
+ const gasPolicyId = options.gasPolicyIdOverride ?? resolveGasPolicyId(program2, cfg);
4049
4147
  if (gasSponsored && !gasPolicyId) {
4050
4148
  throw errInvalidArgs(
4051
4149
  "Gas sponsorship requires a gas policy ID. Set one with --gas-policy-id or `alchemy config set evm-gas-policy-id <id>`."
@@ -5083,7 +5181,11 @@ async function performApprove(program2, spenderArg, opts) {
5083
5181
  }
5084
5182
  validateApprovalMode(opts);
5085
5183
  const signer = parseSignerOpt(opts.signer);
5086
- const { client, network, address: from, paymaster } = buildWalletClient(program2, { signer });
5184
+ const gasPolicyIdOverride = await ensureGasPolicyResolved(program2);
5185
+ const { client, network, address: from, paymaster } = buildWalletClient(program2, {
5186
+ signer,
5187
+ ...gasPolicyIdOverride && { gasPolicyIdOverride }
5188
+ });
5087
5189
  const rpcClient = clientFromFlags(program2);
5088
5190
  const tokenMeta = await fetchTokenDecimals(program2, opts.tokenAddress);
5089
5191
  const approval = buildApprovalRequest(opts, tokenMeta);
@@ -5559,7 +5661,11 @@ async function performContractCall(program2, addressArg, functionArg, opts) {
5559
5661
  const { abi, functionName } = resolveAbi(functionArg, opts);
5560
5662
  const args = parseArgs(opts.args);
5561
5663
  const signer = parseSignerOpt(opts.signer);
5562
- const { client, network, address: from, paymaster } = buildWalletClient(program2, { signer });
5664
+ const gasPolicyIdOverride = await ensureGasPolicyResolved(program2);
5665
+ const { client, network, address: from, paymaster } = buildWalletClient(program2, {
5666
+ signer,
5667
+ ...gasPolicyIdOverride && { gasPolicyIdOverride }
5668
+ });
5563
5669
  const rpcClient = clientFromFlags(program2);
5564
5670
  const contractAddress = await resolveAddress(addressArg, rpcClient);
5565
5671
  const data = encodeFunctionData2({ abi, functionName, args });
@@ -6722,7 +6828,7 @@ Examples:
6722
6828
  dryRun: opts.dryRun
6723
6829
  });
6724
6830
  } catch (err) {
6725
- const { exitWithError: exitWithError2 } = await import("./errors-E2P6WHTX.js");
6831
+ const { exitWithError: exitWithError2 } = await import("./errors-A53DVJDY.js");
6726
6832
  exitWithError2(err);
6727
6833
  }
6728
6834
  });
@@ -6731,7 +6837,11 @@ async function performEvmSend(program2, toArg, amountArg, tokenAddress, opts = {
6731
6837
  if (tokenAddress) {
6732
6838
  validateAddress(tokenAddress);
6733
6839
  }
6734
- const { client, network, address: from, paymaster } = buildWalletClient(program2, { signer: opts.signer });
6840
+ const gasPolicyIdOverride = await ensureGasPolicyResolved(program2);
6841
+ const { client, network, address: from, paymaster } = buildWalletClient(program2, {
6842
+ signer: opts.signer,
6843
+ ...gasPolicyIdOverride && { gasPolicyIdOverride }
6844
+ });
6735
6845
  const rpcClient = clientFromFlags(program2);
6736
6846
  const to = await resolveAddress(toArg, rpcClient);
6737
6847
  let decimals;
@@ -7155,7 +7265,11 @@ async function performSwapExecute(program2, opts) {
7155
7265
  validateAddress(opts.from);
7156
7266
  validateAddress(opts.to);
7157
7267
  const signer = parseSignerOpt(opts.signer);
7158
- const { client, network, address: from, paymaster } = buildWalletClient(program2, { signer });
7268
+ const gasPolicyIdOverride = await ensureGasPolicyResolved(program2);
7269
+ const { client, network, address: from, paymaster } = buildWalletClient(program2, {
7270
+ signer,
7271
+ ...gasPolicyIdOverride && { gasPolicyIdOverride }
7272
+ });
7159
7273
  const swapClient = client.extend(swapActions);
7160
7274
  const fromInfo = await resolveTokenInfo(network, program2, opts.from);
7161
7275
  const rawAmount = parseAmount(opts.amount, fromInfo.decimals);
@@ -7348,6 +7462,174 @@ function registerEvm(program2) {
7348
7462
  registerSimulate(cmd);
7349
7463
  }
7350
7464
 
7465
+ // src/commands/gas-manager.ts
7466
+ function summariseNetworks(p) {
7467
+ return p.networks.map(fromAdminNetworkId).join(", ");
7468
+ }
7469
+ function policyToRow(p) {
7470
+ return [
7471
+ p.policyId,
7472
+ p.policyName,
7473
+ p.policyType,
7474
+ p.status === "active" ? green(p.status) : dim(p.status),
7475
+ summariseNetworks(p) || dim("(none)")
7476
+ ];
7477
+ }
7478
+ function policyToJSON(p) {
7479
+ return {
7480
+ policyId: p.policyId,
7481
+ policyName: p.policyName,
7482
+ policyType: p.policyType,
7483
+ status: p.status,
7484
+ appId: p.appId,
7485
+ networks: p.networks,
7486
+ networkSlugs: p.networks.map(fromAdminNetworkId),
7487
+ policyState: p.policyState ?? null,
7488
+ lastUpdatedUnix: p.lastUpdatedUnix ?? null,
7489
+ policyVersion: p.policyVersion ?? null
7490
+ };
7491
+ }
7492
+ function requireAppId(program2, opts) {
7493
+ if (opts.appId) return opts.appId;
7494
+ const resolved = resolveAppId(program2);
7495
+ if (!resolved) throw errAppRequired();
7496
+ return resolved;
7497
+ }
7498
+ function parseTypeFilter(value) {
7499
+ if (!value) return null;
7500
+ if (value === "sponsorship" || value === "erc20" || value === "solana") return value;
7501
+ throw errInvalidArgs(`Unknown --type ${value}. Expected one of: sponsorship, erc20, solana.`);
7502
+ }
7503
+ function parseStatusFilter(value) {
7504
+ if (!value) return null;
7505
+ if (value === "active" || value === "inactive") return value;
7506
+ throw errInvalidArgs(`Unknown --status ${value}. Expected one of: active, inactive.`);
7507
+ }
7508
+ function registerGasManager(program2) {
7509
+ const cmd = program2.command("gas-manager").description("Manage Alchemy Gas Manager policies");
7510
+ const policyCmd = cmd.command("policy").description("Manage gas sponsorship policies");
7511
+ policyCmd.command("list").description("List gas policies for the default app").option("--app-id <id>", "Override the default app ID").option("--type <type>", "Filter by policy type (sponsorship | erc20 | solana)").option("--network <slug>", "Filter by network slug (e.g. eth-mainnet)").option("--status <status>", "Filter by status (active | inactive)").action(async (opts) => {
7512
+ try {
7513
+ const client = gasManagerClientFromFlags(program2);
7514
+ const appId = requireAppId(program2, opts);
7515
+ const typeFilter = parseTypeFilter(opts.type);
7516
+ const statusFilter = parseStatusFilter(opts.status);
7517
+ const networkFilter = opts.network ? toAdminNetworkId(opts.network) : null;
7518
+ const policies = await withSpinner(
7519
+ "Fetching policies\u2026",
7520
+ "Policies fetched",
7521
+ () => client.listAllPolicies({ appId })
7522
+ );
7523
+ const filtered = policies.filter((p) => {
7524
+ if (typeFilter && p.policyType !== typeFilter) return false;
7525
+ if (statusFilter && p.status !== statusFilter) return false;
7526
+ if (networkFilter && !p.networks.includes(networkFilter)) return false;
7527
+ return true;
7528
+ });
7529
+ if (isJSONMode()) {
7530
+ printJSON({ appId, policies: filtered.map(policyToJSON) });
7531
+ return;
7532
+ }
7533
+ if (filtered.length === 0) {
7534
+ console.log(
7535
+ `
7536
+ ${dim(`No policies for app ${appId}${networkFilter ? ` on ${opts.network}` : ""}.`)}`
7537
+ );
7538
+ console.log(
7539
+ ` ${dim("Create one with: alchemy gas-manager policy create")}`
7540
+ );
7541
+ return;
7542
+ }
7543
+ printTable(
7544
+ ["Policy ID", "Name", "Type", "Status", "Networks"],
7545
+ filtered.map(policyToRow)
7546
+ );
7547
+ console.log(`
7548
+ ${dim(`${filtered.length} policies (app ${appId}).`)}`);
7549
+ } catch (err) {
7550
+ exitWithError(err);
7551
+ }
7552
+ });
7553
+ policyCmd.command("get <policy-id>").description("Show details for a single policy").action(async (policyId) => {
7554
+ try {
7555
+ const client = gasManagerClientFromFlags(program2);
7556
+ const policy = await withSpinner(
7557
+ "Fetching policy\u2026",
7558
+ "Policy fetched",
7559
+ () => client.getPolicy(policyId)
7560
+ );
7561
+ if (isJSONMode()) {
7562
+ printJSON(policyToJSON(policy));
7563
+ return;
7564
+ }
7565
+ printKeyValue([
7566
+ ["Policy ID", policy.policyId],
7567
+ ["Name", policy.policyName],
7568
+ ["Type", policy.policyType],
7569
+ ["Status", policy.status === "active" ? green("active") : dim(policy.status)],
7570
+ ["App", policy.appId],
7571
+ ["Networks", summariseNetworks(policy) || dim("(none)")],
7572
+ ...policy.lastUpdatedUnix ? [["Updated", policy.lastUpdatedUnix]] : []
7573
+ ]);
7574
+ } catch (err) {
7575
+ exitWithError(err);
7576
+ }
7577
+ });
7578
+ policyCmd.command("create").description("Create a new gas policy interactively").option("--type <type>", "Policy type (sponsorship | solana)", "sponsorship").action(async (opts) => {
7579
+ try {
7580
+ const type = parseTypeFilter(opts.type ?? "sponsorship");
7581
+ if (type === "erc20") {
7582
+ throw errInvalidArgs(
7583
+ "ERC-20 policies are not supported in `gas-manager policy create` yet. Create them in the Alchemy dashboard."
7584
+ );
7585
+ }
7586
+ if (!isInteractiveAllowed(program2)) {
7587
+ throw errInvalidArgs(
7588
+ "Policy creation requires an interactive terminal. Create policies in the Alchemy dashboard for non-interactive environments."
7589
+ );
7590
+ }
7591
+ const flavor = type === "solana" ? "solana" : "sponsorship";
7592
+ const network = flavor === "solana" ? resolveSolanaNetwork(program2) : resolveNetwork(program2);
7593
+ const result = await createPolicyInteractive({
7594
+ flavor,
7595
+ network,
7596
+ program: program2
7597
+ });
7598
+ if (!result) return;
7599
+ if (isJSONMode()) {
7600
+ printJSON({
7601
+ policyId: result.policyId,
7602
+ status: result.status,
7603
+ activated: result.activated
7604
+ });
7605
+ }
7606
+ } catch (err) {
7607
+ exitWithError(err);
7608
+ }
7609
+ });
7610
+ policyCmd.command("activate <policy-id>").description("Activate a policy so it can be used for sponsorship").action(async (policyId) => {
7611
+ try {
7612
+ const client = gasManagerClientFromFlags(program2);
7613
+ const policy = await withSpinner(
7614
+ "Activating policy\u2026",
7615
+ "Policy active",
7616
+ () => client.setPolicyStatus(policyId, "active")
7617
+ );
7618
+ if (isJSONMode()) {
7619
+ printJSON(policyToJSON(policy));
7620
+ return;
7621
+ }
7622
+ printKeyValue([
7623
+ ["Policy ID", policy.policyId],
7624
+ ["Name", policy.policyName],
7625
+ ["Status", green(policy.status)]
7626
+ ]);
7627
+ } catch (err) {
7628
+ exitWithError(err);
7629
+ }
7630
+ });
7631
+ }
7632
+
7351
7633
  // src/commands/bridge.ts
7352
7634
  import {
7353
7635
  swapActions as swapActions2
@@ -7548,7 +7830,11 @@ async function performBridgeExecute(program2, opts) {
7548
7830
  const toChainId = bridgeDestinationChainId(opts.toNetwork);
7549
7831
  validateAddress(opts.to);
7550
7832
  const signer = parseSignerOpt(opts.signer);
7551
- const { client, network, address: from, paymaster } = buildWalletClient(program2, { signer });
7833
+ const gasPolicyIdOverride = await ensureGasPolicyResolved(program2);
7834
+ const { client, network, address: from, paymaster } = buildWalletClient(program2, {
7835
+ signer,
7836
+ ...gasPolicyIdOverride && { gasPolicyIdOverride }
7837
+ });
7552
7838
  validateBridgeNetworks(network, opts.toNetwork);
7553
7839
  const swapClient = client.extend(swapActions2);
7554
7840
  const fromInfo = await resolveTokenInfo2(network, program2, opts.from);
@@ -8298,7 +8584,7 @@ async function flushProcessOutput() {
8298
8584
  }
8299
8585
  program.name("alchemy").description(
8300
8586
  "The Alchemy CLI lets you query blockchain data, call JSON-RPC methods, and manage your Alchemy configuration."
8301
- ).version("0.7.4", "-v, --version", "display CLI version").option("--api-key <key>", "Alchemy API key (env: ALCHEMY_API_KEY)").option(
8587
+ ).version("0.8.0", "-v, --version", "display CLI version").option("--api-key <key>", "Alchemy API key (env: ALCHEMY_API_KEY)").option(
8302
8588
  "-n, --network <network>",
8303
8589
  "Target network (default: eth-mainnet) (env: ALCHEMY_NETWORK)"
8304
8590
  ).option("--x402", "Use x402 wallet-based gateway auth").option(
@@ -8485,11 +8771,11 @@ ${styledLine}`;
8485
8771
  "wallet"
8486
8772
  ];
8487
8773
  if (!skipAppPrompt.includes(cmdName) && isInteractiveAllowed(program) && !opts.apiKey && !process.env.ALCHEMY_API_KEY) {
8488
- const { resolveAuthToken: resolveAuthToken2 } = await import("./resolve-WXT5ZCUK.js");
8774
+ const { resolveAuthToken: resolveAuthToken2 } = await import("./resolve-N3SX252M.js");
8489
8775
  const authToken = resolveAuthToken2(cfg);
8490
8776
  const hasApiKey = Boolean(cfg.api_key?.trim() || cfg.app?.apiKey);
8491
8777
  if (authToken && !hasApiKey) {
8492
- const { selectAppAfterAuth } = await import("./auth-F2IXC6CM.js");
8778
+ const { selectAppAfterAuth } = await import("./auth-RINQSQDT.js");
8493
8779
  console.log("");
8494
8780
  console.log(` No app selected. Please select an app to continue.`);
8495
8781
  await selectAppAfterAuth(authToken);
@@ -8524,7 +8810,7 @@ ${styledLine}`;
8524
8810
  if (isInteractiveAllowed(program)) {
8525
8811
  let latestForInteractiveStartup = null;
8526
8812
  if (shouldRunOnboarding(program, cfg)) {
8527
- const { runOnboarding } = await import("./onboarding-CT4RRH6O.js");
8813
+ const { runOnboarding } = await import("./onboarding-YHYXW4F3.js");
8528
8814
  const latest = getAvailableUpdateOnce();
8529
8815
  const completed = await runOnboarding(program, latest);
8530
8816
  updateShownDuringInteractiveStartup = Boolean(latest);
@@ -8538,7 +8824,7 @@ ${styledLine}`;
8538
8824
  latestForInteractiveStartup
8539
8825
  );
8540
8826
  }
8541
- const { startREPL } = await import("./interactive-MHAC5WQI.js");
8827
+ const { startREPL } = await import("./interactive-6R3VKAPQ.js");
8542
8828
  program.exitOverride();
8543
8829
  program.configureOutput({
8544
8830
  writeErr: () => {
@@ -8553,6 +8839,7 @@ registerEvm(program);
8553
8839
  registerSolana(program);
8554
8840
  registerXchain(program);
8555
8841
  registerWallets(program);
8842
+ registerGasManager(program);
8556
8843
  registerApps(program);
8557
8844
  registerWebhooks(program);
8558
8845
  registerAuth(program);
@@ -2,14 +2,14 @@
2
2
  if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
3
3
  import {
4
4
  getSetupMethod
5
- } from "./chunk-R4W44A6E.js";
6
- import "./chunk-64A5W4M2.js";
5
+ } from "./chunk-GNOTKJF4.js";
6
+ import "./chunk-L7VFXQSF.js";
7
7
  import {
8
8
  getRPCNetworkIds
9
- } from "./chunk-K6V3R7SH.js";
9
+ } from "./chunk-JWLZAO7S.js";
10
10
  import {
11
11
  getUpdateNoticeLines
12
- } from "./chunk-N36ZNOVV.js";
12
+ } from "./chunk-76ZO4UJ4.js";
13
13
  import {
14
14
  bold,
15
15
  brand,
@@ -17,18 +17,18 @@ import {
17
17
  dim,
18
18
  green,
19
19
  setBrandedHelpSuppressed
20
- } from "./chunk-5IL2PMZ6.js";
20
+ } from "./chunk-DGZYRBXR.js";
21
21
  import {
22
22
  configDir,
23
23
  load
24
- } from "./chunk-JUCUKTP3.js";
24
+ } from "./chunk-ROBA7SR7.js";
25
25
  import {
26
26
  bgRgb,
27
27
  isJSONMode,
28
28
  noColor,
29
29
  rgb,
30
30
  setReplMode
31
- } from "./chunk-2BALTY22.js";
31
+ } from "./chunk-46LMXT54.js";
32
32
 
33
33
  // src/commands/interactive.ts
34
34
  import * as readline from "readline";
@@ -2,7 +2,7 @@
2
2
  if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
3
3
  import {
4
4
  getUpdateNoticeLines
5
- } from "./chunk-N36ZNOVV.js";
5
+ } from "./chunk-76ZO4UJ4.js";
6
6
  import {
7
7
  bold,
8
8
  brand,
@@ -10,12 +10,12 @@ import {
10
10
  dim,
11
11
  green,
12
12
  promptText
13
- } from "./chunk-5IL2PMZ6.js";
13
+ } from "./chunk-DGZYRBXR.js";
14
14
  import {
15
15
  load,
16
16
  save
17
- } from "./chunk-JUCUKTP3.js";
18
- import "./chunk-2BALTY22.js";
17
+ } from "./chunk-ROBA7SR7.js";
18
+ import "./chunk-46LMXT54.js";
19
19
 
20
20
  // src/commands/onboarding.ts
21
21
  async function runOnboarding(_program, latestUpdate = null) {
@@ -38,7 +38,7 @@ async function runOnboarding(_program, latestUpdate = null) {
38
38
  if (answer === null) {
39
39
  return false;
40
40
  }
41
- const { performBrowserLogin, AUTH_PORT, getLoginUrl } = await import("./auth-GD7BJOMK.js");
41
+ const { performBrowserLogin, AUTH_PORT, getLoginUrl } = await import("./auth-JPRZE2MA.js");
42
42
  console.log(` Opening browser to log in...`);
43
43
  console.log(` ${dim(getLoginUrl(AUTH_PORT))}`);
44
44
  console.log(` ${dim("Waiting for authentication...")}`);
@@ -51,7 +51,7 @@ async function runOnboarding(_program, latestUpdate = null) {
51
51
  auth_token_expires_at: result.expiresAt
52
52
  });
53
53
  console.log(` ${green("\u2713")} Logged in successfully`);
54
- const { selectAppAfterAuth } = await import("./auth-F2IXC6CM.js");
54
+ const { selectAppAfterAuth } = await import("./auth-RINQSQDT.js");
55
55
  await selectAppAfterAuth(result.token);
56
56
  return true;
57
57
  } catch (err) {
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
3
+ import {
4
+ createPolicyInteractive,
5
+ errNotLoggedInForPolicyLookup,
6
+ errSponsorshipNeedsPolicy,
7
+ selectOrCreatePolicy
8
+ } from "./chunk-5Y7UQ27V.js";
9
+ import "./chunk-JWLZAO7S.js";
10
+ import "./chunk-DGZYRBXR.js";
11
+ import "./chunk-ROBA7SR7.js";
12
+ import "./chunk-46LMXT54.js";
13
+ export {
14
+ createPolicyInteractive,
15
+ errNotLoggedInForPolicyLookup,
16
+ errSponsorshipNeedsPolicy,
17
+ selectOrCreatePolicy
18
+ };