@alchemy/cli 0.7.4-alpha.37 → 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.
@@ -11,8 +11,8 @@ import {
11
11
  prepareLogin,
12
12
  revokeToken,
13
13
  waitForCallback
14
- } from "./chunk-WCZIVY4O.js";
15
- import "./chunk-MYHXAACL.js";
14
+ } from "./chunk-NGF46GZP.js";
15
+ import "./chunk-46LMXT54.js";
16
16
  export {
17
17
  AUTH_PORT,
18
18
  DEFAULT_EXPIRES_IN_SECONDS,
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
3
+ import {
4
+ registerAuth,
5
+ selectAppAfterAuth
6
+ } from "./chunk-EKS2THJU.js";
7
+ import "./chunk-NGF46GZP.js";
8
+ import "./chunk-L7VFXQSF.js";
9
+ import "./chunk-JWLZAO7S.js";
10
+ import "./chunk-DGZYRBXR.js";
11
+ import "./chunk-ROBA7SR7.js";
12
+ import "./chunk-46LMXT54.js";
13
+ export {
14
+ registerAuth,
15
+ selectAppAfterAuth
16
+ };
@@ -375,6 +375,13 @@ function errAccessKeyRequired() {
375
375
  "Get an access key: https://www.alchemy.com/docs/reference/admin-api/overview"
376
376
  );
377
377
  }
378
+ function errLoginRequired() {
379
+ return new CLIError(
380
+ ErrorCode.AUTH_REQUIRED,
381
+ "Sign in to Alchemy to continue. Run 'alchemy auth login', then retry.",
382
+ "alchemy auth login"
383
+ );
384
+ }
378
385
  function errInvalidAPIKey(details) {
379
386
  return new CLIError(
380
387
  ErrorCode.INVALID_API_KEY,
@@ -448,8 +455,8 @@ function errAppRequired() {
448
455
  function errWalletKeyRequired() {
449
456
  return new CLIError(
450
457
  ErrorCode.AUTH_REQUIRED,
451
- "Wallet key required for x402. Set ALCHEMY_WALLET_KEY, run 'alchemy wallet connect --mode local', or use --wallet-key-file.",
452
- "alchemy wallet connect --mode local"
458
+ "Wallet key required for x402. Set ALCHEMY_WALLET_KEY, run 'alchemy wallet connect --mode local --chain evm', or use --wallet-key-file.",
459
+ "alchemy wallet connect --mode local --chain evm"
453
460
  );
454
461
  }
455
462
  function errSessionExpired() {
@@ -469,8 +476,8 @@ function errNoActiveSession() {
469
476
  function errSolanaWalletKeyRequired() {
470
477
  return new CLIError(
471
478
  ErrorCode.AUTH_REQUIRED,
472
- "Solana wallet key required. Set ALCHEMY_SOLANA_WALLET_KEY, run 'alchemy wallet connect --mode local', or use --solana-wallet-key-file.",
473
- "alchemy wallet connect --mode local"
479
+ "Solana wallet key required. Set ALCHEMY_SOLANA_WALLET_KEY, run 'alchemy wallet connect --mode local --chain solana', or use --solana-wallet-key-file.",
480
+ "alchemy wallet connect --mode local --chain solana"
474
481
  );
475
482
  }
476
483
  function errSolanaTransactionFailed(details) {
@@ -541,6 +548,7 @@ export {
541
548
  CLIError,
542
549
  errAuthRequired,
543
550
  errAccessKeyRequired,
551
+ errLoginRequired,
544
552
  errInvalidAPIKey,
545
553
  errNetworkNotEnabled,
546
554
  errNetwork,
@@ -0,0 +1,186 @@
1
+ #!/usr/bin/env node
2
+ if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
3
+ import {
4
+ gasManagerClientFromFlags,
5
+ toAdminNetworkId
6
+ } from "./chunk-JWLZAO7S.js";
7
+ import {
8
+ dim,
9
+ green,
10
+ promptAutocomplete,
11
+ promptConfirm,
12
+ promptText,
13
+ withSpinner
14
+ } from "./chunk-DGZYRBXR.js";
15
+ import {
16
+ load,
17
+ save
18
+ } from "./chunk-ROBA7SR7.js";
19
+ import {
20
+ errAppRequired,
21
+ errInvalidArgs,
22
+ errLoginRequired
23
+ } from "./chunk-46LMXT54.js";
24
+
25
+ // src/lib/policy-prompt.ts
26
+ var CREATE_NEW_SENTINEL = "__create_new__";
27
+ var DEFAULT_SPONSORSHIP_EXPIRY_MS = "600000";
28
+ var DEFAULT_SOLANA_MAX_COUNT = "1000";
29
+ function flavorNoun(flavor) {
30
+ return flavor === "solana" ? "fee sponsorship" : "gas sponsorship";
31
+ }
32
+ async function selectOrCreatePolicy(opts) {
33
+ const cfg = load();
34
+ const appId = cfg.app?.id;
35
+ if (!appId) throw errAppRequired();
36
+ const client = opts.client ?? gasManagerClientFromFlags(opts.program);
37
+ const flavorLabel = flavorNoun(opts.flavor);
38
+ const policies = await withSpinner(
39
+ "Fetching gas policies\u2026",
40
+ "Policies fetched",
41
+ () => client.listAllPolicies({ appId })
42
+ );
43
+ const matching = filterPolicies(policies, opts.flavor, opts.network);
44
+ let selectedId = null;
45
+ if (matching.length === 0) {
46
+ console.log(
47
+ ` ${dim(`No ${flavorLabel} policies found for ${opts.network} on app ${appId}. Let's create one.`)}`
48
+ );
49
+ const created = await runCreate(opts, client, appId);
50
+ if (!created) return null;
51
+ selectedId = created.policyId;
52
+ } else {
53
+ const selected = await promptAutocomplete({
54
+ message: `Select a ${flavorLabel} policy for ${opts.network}`,
55
+ placeholder: "Policy name or ID",
56
+ options: [
57
+ ...matching.map((p) => ({
58
+ label: formatPolicyOption(p),
59
+ value: p.policyId
60
+ })),
61
+ { label: "Create a new policy", value: CREATE_NEW_SENTINEL }
62
+ ],
63
+ cancelMessage: "Cancelled policy selection.",
64
+ commitLabel: null
65
+ });
66
+ if (selected === null) return null;
67
+ if (selected === CREATE_NEW_SENTINEL) {
68
+ const created = await runCreate(opts, client, appId);
69
+ if (!created) return null;
70
+ selectedId = created.policyId;
71
+ } else {
72
+ selectedId = selected;
73
+ }
74
+ }
75
+ if (!opts.skipPersistPrompt && selectedId) {
76
+ await maybePersist(opts.flavor, selectedId);
77
+ }
78
+ return selectedId;
79
+ }
80
+ async function createPolicyInteractive(opts) {
81
+ const cfg = load();
82
+ const appId = cfg.app?.id;
83
+ if (!appId) throw errAppRequired();
84
+ const client = opts.client ?? gasManagerClientFromFlags(opts.program);
85
+ const result = await runCreate(opts, client, appId);
86
+ return result;
87
+ }
88
+ function filterPolicies(policies, flavor, network) {
89
+ const adminId = toAdminNetworkId(network);
90
+ return policies.filter((p) => {
91
+ if (p.policyType !== flavor) return false;
92
+ if (!Array.isArray(p.networks)) return false;
93
+ return p.networks.includes(adminId);
94
+ });
95
+ }
96
+ function formatPolicyOption(p) {
97
+ const status = p.status === "active" ? green("active") : dim(p.status);
98
+ return `${p.policyName} (${p.policyId.slice(0, 10)}\u2026) \u2014 ${status}`;
99
+ }
100
+ async function runCreate(opts, client, appId) {
101
+ const name = await promptText({
102
+ message: "Policy name",
103
+ cancelMessage: "Cancelled policy creation."
104
+ });
105
+ if (name === null) return null;
106
+ if (!name.trim()) {
107
+ console.log(` ${dim("Skipped policy creation (no name).")}`);
108
+ return null;
109
+ }
110
+ const adminNetworkId = toAdminNetworkId(opts.network);
111
+ const nowUnix = String(Math.floor(Date.now() / 1e3));
112
+ const payload = opts.flavor === "sponsorship" ? {
113
+ policyName: name.trim(),
114
+ policyType: "sponsorship",
115
+ appId,
116
+ networks: [adminNetworkId],
117
+ rules: {
118
+ startTimeUnix: nowUnix,
119
+ sponsorshipExpiryMs: DEFAULT_SPONSORSHIP_EXPIRY_MS
120
+ }
121
+ } : {
122
+ policyName: name.trim(),
123
+ policyType: "solana",
124
+ appId,
125
+ networks: [adminNetworkId],
126
+ solanaRules: {
127
+ startTimeUnix: nowUnix,
128
+ maxCount: DEFAULT_SOLANA_MAX_COUNT
129
+ }
130
+ };
131
+ const created = await withSpinner(
132
+ "Creating policy\u2026",
133
+ "Policy created",
134
+ () => client.createPolicy(payload)
135
+ );
136
+ console.log(` ${green("\u2713")} Created ${created.policyName} (${created.policyId})`);
137
+ const activate = await promptConfirm({
138
+ message: "Activate this policy now? (required before use)",
139
+ initialValue: true,
140
+ cancelMessage: "Skipped activation."
141
+ });
142
+ let activated = false;
143
+ if (activate === true) {
144
+ await withSpinner(
145
+ "Activating policy\u2026",
146
+ "Policy active",
147
+ () => client.setPolicyStatus(created.policyId, "active")
148
+ );
149
+ activated = true;
150
+ } else {
151
+ console.log(
152
+ ` ${dim("Policy left inactive. Activate later with `alchemy gas-manager policy activate " + created.policyId + "`.")}`
153
+ );
154
+ }
155
+ return { policyId: created.policyId, status: "created", activated };
156
+ }
157
+ async function maybePersist(flavor, policyId) {
158
+ const confirmed = await promptConfirm({
159
+ message: "Save as default policy for this CLI?",
160
+ initialValue: true,
161
+ cancelMessage: "Skipped saving default."
162
+ });
163
+ if (confirmed !== true) return;
164
+ const cfg = load();
165
+ const updated = flavor === "sponsorship" ? { ...cfg, evm_gas_policy_id: policyId } : { ...cfg, solana_fee_policy_id: policyId };
166
+ save(updated);
167
+ const key = flavor === "sponsorship" ? "evm-gas-policy-id" : "solana-fee-policy-id";
168
+ console.log(` ${green("\u2713")} Saved ${key} = ${policyId}`);
169
+ }
170
+ function errSponsorshipNeedsPolicy(flavor) {
171
+ const flag = flavor === "sponsorship" ? "--gas-policy-id" : "--fee-policy-id";
172
+ const label = flavor === "sponsorship" ? "Gas sponsorship" : "Fee sponsorship";
173
+ return errInvalidArgs(
174
+ `${label} requires a policy ID. Run 'alchemy gas-manager policy list' to pick one, pass ${flag} <id>, or run interactively to be prompted.`
175
+ );
176
+ }
177
+ function errNotLoggedInForPolicyLookup() {
178
+ return errLoginRequired();
179
+ }
180
+
181
+ export {
182
+ selectOrCreatePolicy,
183
+ createPolicyInteractive,
184
+ errSponsorshipNeedsPolicy,
185
+ errNotLoggedInForPolicyLookup
186
+ };
@@ -2,10 +2,10 @@
2
2
  if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
3
3
  import {
4
4
  configPath
5
- } from "./chunk-PX2YJ7XC.js";
5
+ } from "./chunk-ROBA7SR7.js";
6
6
  import {
7
7
  esc
8
- } from "./chunk-MYHXAACL.js";
8
+ } from "./chunk-46LMXT54.js";
9
9
 
10
10
  // src/lib/update-check.ts
11
11
  import { execFileSync } from "child_process";
@@ -53,7 +53,7 @@ function semverLT(a, b) {
53
53
  return false;
54
54
  }
55
55
  function currentVersion() {
56
- return true ? "0.7.4-alpha.37" : "0.0.0";
56
+ return true ? "0.8.0" : "0.0.0";
57
57
  }
58
58
  function toUpdateStatus(latestVersion, checkedAt) {
59
59
  const current = currentVersion();
@@ -5,7 +5,7 @@ import {
5
5
  isJSONMode,
6
6
  quiet,
7
7
  rgb
8
- } from "./chunk-MYHXAACL.js";
8
+ } from "./chunk-46LMXT54.js";
9
9
 
10
10
  // src/lib/terminal-ui.ts
11
11
  import * as readline from "readline";
@@ -4,14 +4,14 @@ import {
4
4
  completeLogin,
5
5
  prepareLogin,
6
6
  revokeToken
7
- } from "./chunk-WCZIVY4O.js";
7
+ } from "./chunk-NGF46GZP.js";
8
8
  import {
9
9
  isInteractiveAllowed
10
- } from "./chunk-AUGBYMHT.js";
10
+ } from "./chunk-L7VFXQSF.js";
11
11
  import {
12
12
  AdminClient,
13
13
  resolveAuthToken
14
- } from "./chunk-5HYOZ773.js";
14
+ } from "./chunk-JWLZAO7S.js";
15
15
  import {
16
16
  bold,
17
17
  brand,
@@ -20,13 +20,13 @@ import {
20
20
  promptAutocomplete,
21
21
  promptText,
22
22
  withSpinner
23
- } from "./chunk-HR2UZ6ZU.js";
23
+ } from "./chunk-DGZYRBXR.js";
24
24
  import {
25
25
  configPath,
26
26
  load,
27
27
  maskIf,
28
28
  save
29
- } from "./chunk-PX2YJ7XC.js";
29
+ } from "./chunk-ROBA7SR7.js";
30
30
  import {
31
31
  CLIError,
32
32
  ErrorCode,
@@ -34,7 +34,7 @@ import {
34
34
  exitWithError,
35
35
  isJSONMode,
36
36
  printHuman
37
- } from "./chunk-MYHXAACL.js";
37
+ } from "./chunk-46LMXT54.js";
38
38
 
39
39
  // src/commands/auth.ts
40
40
  function registerAuth(program) {
@@ -2,11 +2,11 @@
2
2
  if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
3
3
  import {
4
4
  isInteractiveAllowed
5
- } from "./chunk-AUGBYMHT.js";
5
+ } from "./chunk-L7VFXQSF.js";
6
6
  import {
7
7
  resolveAuthToken,
8
8
  resolveWalletSession
9
- } from "./chunk-5HYOZ773.js";
9
+ } from "./chunk-JWLZAO7S.js";
10
10
 
11
11
  // src/lib/onboarding.ts
12
12
  var SETUP_CAPABILITY_ORDER = [
@@ -74,14 +74,14 @@ function getSetupCapabilities(cfg) {
74
74
  missing: hasLocalWallet || hasSessionWallet ? [] : ["wallet signer"],
75
75
  nextCommands: hasLocalWallet || hasSessionWallet ? [] : [
76
76
  "alchemy wallet connect",
77
- "alchemy wallet connect --mode local"
77
+ "alchemy wallet connect --mode local --chain evm"
78
78
  ]
79
79
  }),
80
80
  x402: capabilityStatus({
81
81
  complete: x402Ready,
82
82
  satisfiedBy: x402Ready ? "x402_wallet" : null,
83
83
  missing: x402Ready ? [] : ["x402 enabled with wallet key file"],
84
- nextCommands: x402Ready ? [] : ["alchemy wallet connect --mode local && alchemy config set x402 true"]
84
+ nextCommands: x402Ready ? [] : ["alchemy wallet connect --mode local --chain evm && alchemy config set x402 true"]
85
85
  })
86
86
  };
87
87
  }
@@ -115,7 +115,7 @@ function getSetupStatus(cfg) {
115
115
  "alchemy auth",
116
116
  "alchemy config set app",
117
117
  "alchemy config set access-key <key> && alchemy config set app <app-id>",
118
- "alchemy wallet connect --mode local && alchemy config set x402 true"
118
+ "alchemy wallet connect --mode local --chain evm && alchemy config set x402 true"
119
119
  ],
120
120
  capabilities
121
121
  };