@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/README.md +3 -2
- package/dist/auth-23OYLRWN.js +16 -0
- package/dist/{auth-IAM4AMBK.js → auth-KS6VPHHU.js} +2 -2
- package/dist/{chunk-75ICFV5K.js → chunk-3GBDYROJ.js} +1 -1
- package/dist/{chunk-RGVM5SNE.js → chunk-AMGGO36F.js} +1 -1
- package/dist/{chunk-SIIZGMK5.js → chunk-ANONMDDZ.js} +327 -72
- package/dist/{chunk-OVLQH6KL.js → chunk-CTTW4PA4.js} +1 -0
- package/dist/{chunk-TTWOBNJP.js → chunk-D2RUM2DD.js} +4 -4
- package/dist/{chunk-GDLPBPG3.js → chunk-GLKB4JM7.js} +1 -1
- package/dist/{chunk-HGFU4JCS.js → chunk-HRWD4V2P.js} +3 -3
- package/dist/{chunk-L2WODD2D.js → chunk-L5E7GEUU.js} +6 -6
- package/dist/{chunk-MV7O3XBG.js → chunk-PMNRIXJI.js} +1 -1
- package/dist/{chunk-P56HOTPV.js → chunk-VN5JUWHO.js} +2 -2
- package/dist/{errors-T6XE2I2L.js → errors-YPNK3AVF.js} +1 -1
- package/dist/index.js +1148 -184
- package/dist/{interactive-IBR6RN74.js → interactive-D34T7RI6.js} +7 -7
- package/dist/{onboarding-CW7XGRE4.js → onboarding-A7IOH2MX.js} +6 -6
- package/dist/{policy-prompt-4BV5AWVV.js → policy-prompt-V6W7CPAO.js} +5 -5
- package/dist/{resolve-FQ66OWT7.js → resolve-REZCFZZ7.js} +3 -3
- package/package.json +5 -8
- package/dist/auth-6BBITIOZ.js +0 -16
package/dist/index.js
CHANGED
|
@@ -5,32 +5,35 @@ import {
|
|
|
5
5
|
errNotLoggedInForPolicyLookup,
|
|
6
6
|
errSponsorshipNeedsPolicy,
|
|
7
7
|
selectOrCreatePolicy
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-D2RUM2DD.js";
|
|
9
9
|
import {
|
|
10
10
|
registerAuth
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-L5E7GEUU.js";
|
|
12
12
|
import {
|
|
13
13
|
openBrowser
|
|
14
|
-
} from "./chunk-
|
|
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-
|
|
21
|
+
} from "./chunk-VN5JUWHO.js";
|
|
22
22
|
import {
|
|
23
23
|
isInteractiveAllowed
|
|
24
|
-
} from "./chunk-
|
|
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
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
|
218
|
-
if (
|
|
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
|
|
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(
|
|
263
|
-
if (!ADDRESS_RE.test(
|
|
270
|
+
function validateAddress(address3) {
|
|
271
|
+
if (!ADDRESS_RE.test(address3)) {
|
|
264
272
|
throw errInvalidArgs(
|
|
265
|
-
`Invalid 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-
|
|
581
|
-
const { resolveNetwork: resolveNetwork2 } = await import("./resolve-
|
|
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-
|
|
636
|
-
const { resolveSolanaNetwork: resolveSolanaNetwork2 } = await import("./resolve-
|
|
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-
|
|
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(
|
|
1935
|
+
clearTimeout(timeout2);
|
|
1928
1936
|
reject(new WalletConnectInterruptedError());
|
|
1929
1937
|
};
|
|
1930
|
-
const
|
|
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,
|
|
2030
|
-
const addr =
|
|
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,
|
|
2036
|
-
const keyPath = walletKeyPath(prefix,
|
|
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
|
|
2148
|
-
const keyPath = persistWalletKey("wallet-key", key,
|
|
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:
|
|
2151
|
-
return { address:
|
|
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
|
|
2579
|
+
let mode;
|
|
2572
2580
|
if (opts.mode === "session" || opts.mode === "local") {
|
|
2573
|
-
|
|
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 (
|
|
2586
|
+
if (mode === "local") {
|
|
2579
2587
|
throw errInvalidArgs("`--instance-name` is only valid with `--mode session`.");
|
|
2580
2588
|
}
|
|
2581
|
-
|
|
2589
|
+
mode = "session";
|
|
2582
2590
|
}
|
|
2583
2591
|
if (importPath) {
|
|
2584
|
-
if (
|
|
2592
|
+
if (mode === "session") {
|
|
2585
2593
|
throw errInvalidArgs("`--import` is only valid with `--mode local`.");
|
|
2586
2594
|
}
|
|
2587
|
-
|
|
2595
|
+
mode = "local";
|
|
2588
2596
|
}
|
|
2589
|
-
if (!
|
|
2597
|
+
if (!mode) {
|
|
2590
2598
|
if (!isInteractiveAllowed(program2)) {
|
|
2591
|
-
|
|
2592
|
-
|
|
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 (
|
|
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
|
|
3101
|
-
const url = withQuery(new URL(path.replace(/^\//, ""),
|
|
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
|
|
3108
|
-
const url = withQuery(new URL(path.replace(/^\//, ""),
|
|
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
|
|
3118
|
-
const url = withQuery(new URL(path.replace(/^\//, ""),
|
|
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
|
|
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
|
-
|
|
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
|
|
4147
|
-
const
|
|
4148
|
-
|
|
4149
|
-
|
|
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
|
-
|
|
4154
|
-
|
|
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
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
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
|
-
|
|
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 =
|
|
4742
|
+
const chain = walletNetworkToChain(network);
|
|
4313
4743
|
if (!chain) {
|
|
4314
|
-
const supported =
|
|
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
|
|
4932
|
+
const address3 = args.session.evmAddress;
|
|
4503
4933
|
return toAccount({
|
|
4504
|
-
address:
|
|
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:
|
|
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:
|
|
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(
|
|
5699
|
-
return
|
|
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
|
|
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", [
|
|
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:
|
|
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",
|
|
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: [
|
|
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
|
|
7425
|
+
const address3 = await resolveAddress(addressInput, client);
|
|
6484
7426
|
const params = {
|
|
6485
|
-
owner:
|
|
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:
|
|
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 (
|
|
7503
|
+
cmd.command("contract <address>").description("Get NFT contract metadata").action(async (address3) => {
|
|
6562
7504
|
try {
|
|
6563
|
-
validateAddress(
|
|
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:
|
|
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
|
|
6707
|
-
const params = [
|
|
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",
|
|
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", [
|
|
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
|
|
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 (
|
|
6907
|
-
filter.fromAddress =
|
|
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-
|
|
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,
|
|
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(
|
|
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:
|
|
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(
|
|
7744
|
-
return
|
|
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(
|
|
8437
|
-
return
|
|
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.
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
10594
|
+
const { startREPL } = await import("./interactive-D34T7RI6.js");
|
|
9631
10595
|
program.exitOverride();
|
|
9632
10596
|
program.configureOutput({
|
|
9633
10597
|
writeErr: () => {
|