@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/{auth-GD7BJOMK.js → auth-JPRZE2MA.js} +2 -2
- package/dist/auth-RINQSQDT.js +16 -0
- package/dist/{chunk-2BALTY22.js → chunk-46LMXT54.js} +8 -0
- package/dist/chunk-5Y7UQ27V.js +186 -0
- package/dist/{chunk-N36ZNOVV.js → chunk-76ZO4UJ4.js} +3 -3
- package/dist/{chunk-5IL2PMZ6.js → chunk-DGZYRBXR.js} +1 -1
- package/dist/{chunk-XSN4XA5Z.js → chunk-EKS2THJU.js} +6 -6
- package/dist/{chunk-R4W44A6E.js → chunk-GNOTKJF4.js} +2 -2
- package/dist/{chunk-K6V3R7SH.js → chunk-JWLZAO7S.js} +182 -2
- package/dist/{chunk-64A5W4M2.js → chunk-L7VFXQSF.js} +1 -1
- package/dist/{chunk-C5HNQOLB.js → chunk-NGF46GZP.js} +1 -1
- package/dist/{chunk-JUCUKTP3.js → chunk-ROBA7SR7.js} +1 -1
- package/dist/{errors-E2P6WHTX.js → errors-A53DVJDY.js} +3 -1
- package/dist/index.js +327 -40
- package/dist/{interactive-MHAC5WQI.js → interactive-6R3VKAPQ.js} +7 -7
- package/dist/{onboarding-CT4RRH6O.js → onboarding-YHYXW4F3.js} +6 -6
- package/dist/policy-prompt-7AUZOA7S.js +18 -0
- package/dist/{resolve-WXT5ZCUK.js → resolve-N3SX252M.js} +7 -3
- package/package.json +1 -1
- package/dist/auth-F2IXC6CM.js +0 -16
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-
|
|
11
|
+
} from "./chunk-EKS2THJU.js";
|
|
6
12
|
import {
|
|
7
13
|
openBrowser
|
|
8
|
-
} from "./chunk-
|
|
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-
|
|
21
|
+
} from "./chunk-GNOTKJF4.js";
|
|
16
22
|
import {
|
|
17
23
|
isInteractiveAllowed
|
|
18
|
-
} from "./chunk-
|
|
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-
|
|
56
|
+
} from "./chunk-JWLZAO7S.js";
|
|
47
57
|
import {
|
|
48
58
|
getAvailableUpdate,
|
|
49
59
|
getUpdateStatus,
|
|
50
60
|
printUpdateNotice
|
|
51
|
-
} from "./chunk-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
|
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
|
-
|
|
558
|
-
|
|
559
|
-
|
|
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
|
|
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
|
-
|
|
586
|
-
|
|
587
|
-
|
|
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-
|
|
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
|
|
3198
|
-
if (sponsored
|
|
3199
|
-
|
|
3200
|
-
|
|
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
|
|
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
|
|
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-
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-GNOTKJF4.js";
|
|
6
|
+
import "./chunk-L7VFXQSF.js";
|
|
7
7
|
import {
|
|
8
8
|
getRPCNetworkIds
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-JWLZAO7S.js";
|
|
10
10
|
import {
|
|
11
11
|
getUpdateNoticeLines
|
|
12
|
-
} from "./chunk-
|
|
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-
|
|
20
|
+
} from "./chunk-DGZYRBXR.js";
|
|
21
21
|
import {
|
|
22
22
|
configDir,
|
|
23
23
|
load
|
|
24
|
-
} from "./chunk-
|
|
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-
|
|
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-
|
|
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-
|
|
13
|
+
} from "./chunk-DGZYRBXR.js";
|
|
14
14
|
import {
|
|
15
15
|
load,
|
|
16
16
|
save
|
|
17
|
-
} from "./chunk-
|
|
18
|
-
import "./chunk-
|
|
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-
|
|
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-
|
|
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
|
+
};
|