@alchemy/cli 0.6.2 → 0.7.0-alpha.5
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 +49 -61
- package/dist/auth-I5WFLU46.js +16 -0
- package/dist/{auth-S4DTOWW3.js → auth-JGON2JU6.js} +10 -8
- package/dist/{chunk-TK3HZ5UT.js → chunk-5MXODL63.js} +3 -3
- package/dist/{chunk-NBDWF4ZQ.js → chunk-A6L3WCJN.js} +32 -22
- package/dist/{chunk-BAAQ7ELR.js → chunk-B3R6PRAL.js} +59 -4
- package/dist/{chunk-FFMNT74F.js → chunk-HSKKIATB.js} +125 -76
- package/dist/{chunk-KDMIWPZH.js → chunk-HYCRHNPX.js} +1 -1
- package/dist/chunk-MUT4TFQ5.js +64 -0
- package/dist/{chunk-UMKDYHMO.js → chunk-NT3G6BKD.js} +54 -99
- package/dist/{chunk-ATX65U7J.js → chunk-PKAN5FKD.js} +570 -41
- package/dist/{chunk-56ZVYB4G.js → chunk-QEDAULQ2.js} +263 -222
- package/dist/errors-3CNFGAXT.js +54 -0
- package/dist/index.js +6668 -2166
- package/dist/{interactive-UGD7GYJM.js → interactive-VXPD6N7Z.js} +56 -61
- package/dist/{onboarding-IP4R44EQ.js → onboarding-CEHXSNYD.js} +14 -11
- package/dist/resolve-X7HLVLGA.js +50 -0
- package/package.json +12 -3
- package/scripts/postinstall.cjs +69 -1
- package/dist/auth-QB3BA7AN.js +0 -17
- package/dist/chunk-JQRGILIS.js +0 -53
- package/dist/chunk-T5Z2GJUX.js +0 -331
- package/dist/credential-storage-T6FFW7DG.js +0 -14
- package/dist/resolve-HXKHDOJZ.js +0 -31
package/README.md
CHANGED
|
@@ -67,7 +67,7 @@ Quick usage examples:
|
|
|
67
67
|
alchemy
|
|
68
68
|
|
|
69
69
|
# Agent/script-friendly command
|
|
70
|
-
alchemy balance 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 --json --no-interactive
|
|
70
|
+
alchemy evm data balance 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 --json --no-interactive
|
|
71
71
|
|
|
72
72
|
# Agent checks whether a newer CLI version is available
|
|
73
73
|
alchemy update-check --json --no-interactive
|
|
@@ -91,56 +91,43 @@ Agents can also call `alchemy --json --no-interactive update-check` to retrieve
|
|
|
91
91
|
Run commands as `alchemy <command>`.
|
|
92
92
|
Use `alchemy help` or `alchemy help <command>` for generated command help.
|
|
93
93
|
|
|
94
|
-
###
|
|
94
|
+
### EVM
|
|
95
95
|
|
|
96
96
|
| Command | What it does | Example |
|
|
97
97
|
|---|---|---|
|
|
98
|
-
| `
|
|
99
|
-
| `
|
|
100
|
-
| `
|
|
101
|
-
| `
|
|
102
|
-
| `
|
|
103
|
-
| `
|
|
104
|
-
| `
|
|
105
|
-
| `
|
|
106
|
-
| `
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
|
111
|
-
|
|
112
|
-
| `
|
|
113
|
-
| `
|
|
114
|
-
| `tokens allowance --owner --spender --contract` | Gets ERC-20 allowance | `alchemy tokens allowance --owner 0x... --spender 0x... --contract 0x...` |
|
|
115
|
-
| `nfts [address]` | Lists NFTs owned by an address | `alchemy nfts 0x...` |
|
|
116
|
-
| `nfts metadata --contract <addr> --token-id <id>` | Gets NFT metadata by contract/token | `alchemy nfts metadata --contract 0x... --token-id 1` |
|
|
117
|
-
| `nfts contract <address>` | Gets NFT contract metadata | `alchemy nfts contract 0x...` |
|
|
118
|
-
| `transfers [address]` | Gets transfer history (`alchemy_getAssetTransfers`) | `alchemy transfers 0x... --category erc20,erc721` |
|
|
119
|
-
| `prices symbol <symbols>` | Gets current token prices by symbol | `alchemy prices symbol ETH,USDC` |
|
|
120
|
-
| `prices address --addresses <json>` | Gets current token prices by address/network pairs | `alchemy prices address --addresses '[{"network":"eth-mainnet","address":"0x..."}]'` |
|
|
121
|
-
| `prices historical --body <json>` | Gets historical prices | `alchemy prices historical --body '{"symbol":"ETH","startTime":"...","endTime":"..."}'` |
|
|
122
|
-
| `portfolio tokens --body <json>` | Gets token portfolio data | `alchemy portfolio tokens --body '{...}'` |
|
|
123
|
-
| `portfolio token-balances --body <json>` | Gets token balance snapshots | `alchemy portfolio token-balances --body '{...}'` |
|
|
124
|
-
| `portfolio nfts --body <json>` | Gets NFT portfolio data | `alchemy portfolio nfts --body '{...}'` |
|
|
125
|
-
| `portfolio nft-contracts --body <json>` | Gets NFT contract portfolio data | `alchemy portfolio nft-contracts --body '{...}'` |
|
|
126
|
-
| `portfolio transactions --body <json>` | Gets portfolio transaction history | `alchemy portfolio transactions --body '{...}'` |
|
|
127
|
-
| `simulate asset-changes --tx <json>` | Simulates asset changes | `alchemy simulate asset-changes --tx '{"from":"0x...","to":"0x..."}'` |
|
|
128
|
-
| `simulate execution --tx <json>` | Simulates execution traces | `alchemy simulate execution --tx '{"from":"0x...","to":"0x..."}'` |
|
|
129
|
-
| `simulate asset-changes-bundle --txs <json>` | Simulates bundle asset changes | `alchemy simulate asset-changes-bundle --txs '[{...}]'` |
|
|
130
|
-
| `simulate execution-bundle --txs <json>` | Simulates bundle execution traces | `alchemy simulate execution-bundle --txs '[{...}]'` |
|
|
98
|
+
| `evm rpc <method> [params...]` | Makes raw Ethereum JSON-RPC calls | `alchemy evm rpc eth_blockNumber` |
|
|
99
|
+
| `evm data balance [address]` | Gets native token balance for an address | `alchemy evm data balance 0x...` |
|
|
100
|
+
| `evm data tokens balances [address]` | Lists ERC-20 balances for an address | `alchemy evm data tokens balances 0x...` |
|
|
101
|
+
| `evm data nfts [address]` | Lists NFTs owned by an address | `alchemy evm data nfts 0x...` |
|
|
102
|
+
| `evm data history [address]` | Gets transfer history (`alchemy_getAssetTransfers`) | `alchemy evm data history 0x... --category erc20,erc721` |
|
|
103
|
+
| `evm data price symbol <symbols>` | Gets current token prices by symbol | `alchemy evm data price symbol ETH,USDC` |
|
|
104
|
+
| `evm data portfolio tokens --body <json>` | Gets token portfolio data | `alchemy evm data portfolio tokens --body '{...}'` |
|
|
105
|
+
| `evm send <to> <amount>` | Sends native tokens or ERC-20 tokens | `alchemy evm send vitalik.eth 0.1 -n base-mainnet` |
|
|
106
|
+
| `evm contract read/call` | Reads or writes smart contracts | `alchemy evm contract read 0x... "balanceOf(address)(uint256)" --args '["0x..."]'` |
|
|
107
|
+
| `evm swap quote/execute` | Swaps tokens on the same chain | `alchemy evm swap quote --from 0xEeee... --to 0xA0b8... --amount 1` |
|
|
108
|
+
| `evm approve <spender_address>` | Approves an ERC-20 token allowance | `alchemy evm approve 0x... --token-address 0x... --amount 10` |
|
|
109
|
+
| `evm status [id]` | Checks transaction or operation status | `alchemy evm status 0x...` |
|
|
110
|
+
| `evm network list` | Lists RPC network IDs for use with `--network` | `alchemy evm network list --search base` |
|
|
111
|
+
| `evm tx/receipt/block/gas/logs` | Fetches common node resources | `alchemy evm block latest` |
|
|
112
|
+
| `evm trace/debug` | Calls Trace and Debug API methods | `alchemy evm trace call '{"to":"0x..."}' '["trace"]' latest` |
|
|
113
|
+
| `evm simulate *` | Calls simulation APIs | `alchemy evm simulate execution --tx '{"to":"0x..."}'` |
|
|
131
114
|
|
|
132
115
|
### Wallets
|
|
133
116
|
|
|
117
|
+
`alchemy wallets` exposes a unified onchain-actions surface. The **session wallet** (Alchemy/Privy-managed, P-256 delegated signer) is the recommended flow; a **local wallet** (private key stored on disk) is supported as an alternative and is currently the only path for Solana.
|
|
118
|
+
|
|
134
119
|
| Command | What it does | Example |
|
|
135
120
|
|---|---|---|
|
|
136
|
-
| `
|
|
137
|
-
| `
|
|
138
|
-
| `
|
|
139
|
-
| `
|
|
140
|
-
| `
|
|
141
|
-
| `
|
|
142
|
-
| `
|
|
143
|
-
| `
|
|
121
|
+
| `wallets connect` | Interactive: choose a session wallet (recommended) or a local wallet. For scripts, pass `--mode <session\|local>`. | `alchemy wallets connect` |
|
|
122
|
+
| `wallets connect --mode local --chain evm` | Create a new local EVM key (non-interactive). `--chain` accepts `evm`, `solana`, or `both`. | `alchemy wallets connect --mode local --chain both` |
|
|
123
|
+
| `wallets connect --mode local --import <path>` | Import an existing EVM private key from a file. | `alchemy wallets connect --mode local --import ./key.txt` |
|
|
124
|
+
| `wallets status [--verify]` | Reports session, local EVM, local Solana, and the active signer. `--verify` reconciles the session with the backend. | `alchemy wallets status --verify` |
|
|
125
|
+
| `wallets address` | Prints addresses for every configured signer. | `alchemy wallets address` |
|
|
126
|
+
| `wallets use <session\|local>` | Selects which signer `evm send`, `evm swap`, `evm approve`, `xchain bridge`, and `evm contract call` use for EVM transactions. | `alchemy wallets use local` |
|
|
127
|
+
| `wallets disconnect` | Revokes the current session (local + backend). Clears `active_signer` if it pointed at the session. | `alchemy wallets disconnect` |
|
|
128
|
+
| `wallets qr [--type <evm\|solana>]` | Renders a configured address as a QR code. | `alchemy wallets qr --type evm` |
|
|
129
|
+
|
|
130
|
+
Per-command override: pass `--signer <session\|local>` to `evm send`, `evm approve`, `evm swap`, `xchain bridge`, or `evm contract call` to override the active signer for a single invocation.
|
|
144
131
|
| `webhooks list` | Lists Notify webhooks | `alchemy webhooks list --webhook-api-key <key>` |
|
|
145
132
|
| `webhooks create --body <json>` | Creates Notify webhook | `alchemy webhooks create --body '{...}' --webhook-api-key <key>` |
|
|
146
133
|
| `webhooks update --body <json>` | Updates Notify webhook | `alchemy webhooks update --body '{...}' --webhook-api-key <key>` |
|
|
@@ -150,9 +137,10 @@ Use `alchemy help` or `alchemy help <command>` for generated command help.
|
|
|
150
137
|
|
|
151
138
|
| Command | What it does | Example |
|
|
152
139
|
|---|---|---|
|
|
153
|
-
| `network list` | Lists RPC network IDs for use with `--network` (e.g. `eth-mainnet`) | `alchemy network list --search ethereum` |
|
|
154
140
|
| `solana rpc <method> [params...]` | Calls Solana JSON-RPC methods | `alchemy solana rpc getBalance '"<pubkey>"'` |
|
|
155
141
|
| `solana das <method> [params...]` | Calls Solana DAS methods | `alchemy solana das getAssetsByOwner '{"ownerAddress":"<pubkey>"}'` |
|
|
142
|
+
| `solana network list` | Lists networks from the Solana namespace | `alchemy solana network list --search solana` |
|
|
143
|
+
| `xchain bridge quote/execute` | Bridges tokens across chains | `alchemy xchain bridge quote --from 0xEeee... --to 0xEeee... --amount 0.1 --to-network base-mainnet -n eth-mainnet` |
|
|
156
144
|
|
|
157
145
|
### CLI Admin
|
|
158
146
|
|
|
@@ -172,7 +160,9 @@ Use `alchemy help` or `alchemy help <command>` for generated command help.
|
|
|
172
160
|
| `apps address-allowlist <id>` | Updates app address allowlist | `alchemy apps address-allowlist <app-id> --addresses 0xabc,0xdef` |
|
|
173
161
|
| `apps origin-allowlist <id>` | Updates app origin allowlist | `alchemy apps origin-allowlist <app-id> --origins https://example.com` |
|
|
174
162
|
| `apps ip-allowlist <id>` | Updates app IP allowlist | `alchemy apps ip-allowlist <app-id> --ips 1.2.3.4,5.6.7.8` |
|
|
175
|
-
| `
|
|
163
|
+
| `doctor` | Runs readiness checks and suggestions | `alchemy doctor` |
|
|
164
|
+
| `install mcp` | Installs Alchemy's remote MCP server config | `alchemy install mcp --client claude --dry-run` |
|
|
165
|
+
| `install skills` | Installs bundled Alchemy skills | `alchemy install skills --client cursor --dry-run` |
|
|
176
166
|
| `update-check` | Checks whether a newer CLI version is available | `alchemy update-check --json --no-interactive` |
|
|
177
167
|
| `config set ...` | Sets config values | `alchemy config set api-key <key>` |
|
|
178
168
|
| `config get <key>` | Gets one config value | `alchemy config get network` |
|
|
@@ -229,20 +219,16 @@ Additional env vars:
|
|
|
229
219
|
| Command | Flags |
|
|
230
220
|
|---|---|
|
|
231
221
|
| `auth login` | `--force`, `-y, --yes` |
|
|
232
|
-
| `nfts` | `--limit <n>`, `--page-key <key>` |
|
|
233
|
-
| `nfts metadata` | `--contract <address>` (required), `--token-id <id>` (required) |
|
|
234
|
-
| `tokens` | `--page-key <key>` |
|
|
235
|
-
| `tokens allowance` | `--owner <address>` (required), `--spender <address>` (required), `--contract <address>` (required) |
|
|
236
|
-
| `
|
|
237
|
-
| `
|
|
238
|
-
| `
|
|
239
|
-
| `portfolio *` | `--body <json>` (required per subcommand) |
|
|
240
|
-
| `simulate *` | `--tx <json>` or `--txs <json>` (required) |
|
|
222
|
+
| `evm data nfts` | `--limit <n>`, `--page-key <key>` |
|
|
223
|
+
| `evm data nfts metadata` | `--contract <address>` (required), `--token-id <id>` (required) |
|
|
224
|
+
| `evm data tokens balances` | `--page-key <key>` |
|
|
225
|
+
| `evm data tokens allowance` | `--owner <address>` (required), `--spender <address>` (required), `--contract <address>` (required) |
|
|
226
|
+
| `evm data history` | `--from-address <address>`, `--to-address <address>`, `--from-block <block>`, `--to-block <block>`, `--category <list>`, `--max-count <n>`, `--page-key <key>` |
|
|
227
|
+
| `evm data price address` | `--addresses <json>` (required) |
|
|
228
|
+
| `evm data price historical` | `--body <json>` (required) |
|
|
229
|
+
| `evm data portfolio *` | `--body <json>` (required per subcommand) |
|
|
230
|
+
| `evm simulate *` | `--tx <json>` or `--txs <json>` (required) |
|
|
241
231
|
| `webhooks *` | `--webhook-api-key <key>` (or `ALCHEMY_WEBHOOK_API_KEY`, `ALCHEMY_NOTIFY_AUTH_TOKEN`, config `webhook-api-key`, or app webhook key) |
|
|
242
|
-
| `bundler send-user-operation` | `--user-op <json>` (required), `--entry-point <address>` (required) |
|
|
243
|
-
| `bundler estimate-user-operation-gas` | `--user-op <json>` (required), `--entry-point <address>` (required), `--state-override <json>` |
|
|
244
|
-
| `bundler get-user-operation-receipt` | `--user-op-hash <hash>` (required) |
|
|
245
|
-
| `gas-manager *` | `--body <json>` (required) |
|
|
246
232
|
| `apps list` | `--cursor <cursor>`, `--limit <n>`, `--all`, `--search <query>`, `--id <appId>` |
|
|
247
233
|
| `apps create` | `--name <name>` (required), `--networks <networks>` (required), `--description <desc>`, `--products <products>`, `--dry-run` |
|
|
248
234
|
| `apps update` | `--name <name>`, `--description <desc>`, `--dry-run` |
|
|
@@ -251,7 +237,9 @@ Additional env vars:
|
|
|
251
237
|
| `apps address-allowlist` | `--addresses <addrs>` (required), `--dry-run` |
|
|
252
238
|
| `apps origin-allowlist` | `--origins <origins>` (required), `--dry-run` |
|
|
253
239
|
| `apps ip-allowlist` | `--ips <ips>` (required), `--dry-run` |
|
|
254
|
-
| `
|
|
240
|
+
| `install mcp` | `--client <claude,cursor,codex,other,all>`, `--dry-run` |
|
|
241
|
+
| `install skills` | `--client <claude,cursor,codex,all>`, `--dry-run` |
|
|
242
|
+
| `evm network list` | `--mainnet-only`, `--testnet-only`, `--search <term>` |
|
|
255
243
|
| `config reset` | `-y, --yes` |
|
|
256
244
|
|
|
257
245
|
## Authentication Reference
|
|
@@ -284,8 +272,8 @@ Run `alchemy` with no command in an interactive terminal:
|
|
|
284
272
|
|
|
285
273
|
```bash
|
|
286
274
|
alchemy
|
|
287
|
-
alchemy ◆ balance 0x...
|
|
288
|
-
alchemy ◆ block latest
|
|
275
|
+
alchemy ◆ evm data balance 0x...
|
|
276
|
+
alchemy ◆ evm block latest
|
|
289
277
|
alchemy ◆ exit
|
|
290
278
|
```
|
|
291
279
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
|
|
3
|
+
import {
|
|
4
|
+
registerAuth,
|
|
5
|
+
selectAppAfterAuth
|
|
6
|
+
} from "./chunk-NT3G6BKD.js";
|
|
7
|
+
import "./chunk-HSKKIATB.js";
|
|
8
|
+
import "./chunk-HYCRHNPX.js";
|
|
9
|
+
import "./chunk-PKAN5FKD.js";
|
|
10
|
+
import "./chunk-A6L3WCJN.js";
|
|
11
|
+
import "./chunk-B3R6PRAL.js";
|
|
12
|
+
import "./chunk-QEDAULQ2.js";
|
|
13
|
+
export {
|
|
14
|
+
registerAuth,
|
|
15
|
+
selectAppAfterAuth
|
|
16
|
+
};
|
|
@@ -2,24 +2,26 @@
|
|
|
2
2
|
if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
|
|
3
3
|
import {
|
|
4
4
|
AUTH_PORT,
|
|
5
|
-
|
|
5
|
+
DEFAULT_EXPIRES_IN_SECONDS,
|
|
6
|
+
completeLogin,
|
|
6
7
|
exchangeCodeForToken,
|
|
7
|
-
|
|
8
|
+
getLoginUrl,
|
|
8
9
|
openBrowser,
|
|
9
10
|
performBrowserLogin,
|
|
10
|
-
|
|
11
|
+
prepareLogin,
|
|
11
12
|
revokeToken,
|
|
12
13
|
waitForCallback
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-
|
|
14
|
+
} from "./chunk-HSKKIATB.js";
|
|
15
|
+
import "./chunk-QEDAULQ2.js";
|
|
15
16
|
export {
|
|
16
17
|
AUTH_PORT,
|
|
17
|
-
|
|
18
|
+
DEFAULT_EXPIRES_IN_SECONDS,
|
|
19
|
+
completeLogin,
|
|
18
20
|
exchangeCodeForToken,
|
|
19
|
-
|
|
21
|
+
getLoginUrl,
|
|
20
22
|
openBrowser,
|
|
21
23
|
performBrowserLogin,
|
|
22
|
-
|
|
24
|
+
prepareLogin,
|
|
23
25
|
revokeToken,
|
|
24
26
|
waitForCallback
|
|
25
27
|
};
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
|
|
3
3
|
import {
|
|
4
4
|
configPath
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-B3R6PRAL.js";
|
|
6
6
|
import {
|
|
7
7
|
esc
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-QEDAULQ2.js";
|
|
9
9
|
|
|
10
10
|
// src/lib/update-check.ts
|
|
11
11
|
import { execFileSync } from "child_process";
|
|
@@ -53,7 +53,7 @@ function semverLT(a, b) {
|
|
|
53
53
|
return false;
|
|
54
54
|
}
|
|
55
55
|
function currentVersion() {
|
|
56
|
-
return true ? "0.
|
|
56
|
+
return true ? "0.7.0-alpha.5" : "0.0.0";
|
|
57
57
|
}
|
|
58
58
|
function toUpdateStatus(latestVersion, checkedAt) {
|
|
59
59
|
const current = currentVersion();
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
isJSONMode,
|
|
6
6
|
quiet,
|
|
7
7
|
rgb
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-QEDAULQ2.js";
|
|
9
9
|
|
|
10
10
|
// src/lib/terminal-ui.ts
|
|
11
11
|
import * as readline from "readline";
|
|
@@ -48,6 +48,9 @@ function suspendStdinKeypressListeners() {
|
|
|
48
48
|
}
|
|
49
49
|
async function runListPrompt(opts) {
|
|
50
50
|
if (!stdin.isTTY || !stdout.isTTY) {
|
|
51
|
+
if (opts.allowMultiple) {
|
|
52
|
+
return { value: opts.initialValues ?? [], cancelled: false };
|
|
53
|
+
}
|
|
51
54
|
const initial = opts.initialValue ?? opts.options.find((o) => !o.disabled)?.value ?? null;
|
|
52
55
|
return { value: initial, cancelled: false };
|
|
53
56
|
}
|
|
@@ -61,7 +64,7 @@ async function runListPrompt(opts) {
|
|
|
61
64
|
0,
|
|
62
65
|
opts.options.findIndex((o) => o.value === opts.initialValue && !o.disabled)
|
|
63
66
|
);
|
|
64
|
-
const selected =
|
|
67
|
+
const selected = new Set(opts.initialValues ?? []);
|
|
65
68
|
const maxVisible = 8;
|
|
66
69
|
let renderedLines = 0;
|
|
67
70
|
const getFiltered = () => {
|
|
@@ -104,10 +107,11 @@ async function runListPrompt(opts) {
|
|
|
104
107
|
const active = start + i === cursor;
|
|
105
108
|
const disabled = option.disabled === true;
|
|
106
109
|
const selectedMark = opts.allowMultiple ? selected.has(option.value) ? ansi.green("\u25C6") : ansi.dim("\u25C7") : active ? ansi.cyan("\u25C6") : ansi.dim("\u25C7");
|
|
110
|
+
const activeMark = active ? ansi.cyan("\u203A") : " ";
|
|
107
111
|
const label = optionLabel(option);
|
|
108
112
|
const value = disabled ? ansi.dim(label) : label;
|
|
109
113
|
const hint = option.hint ? ` ${ansi.dim(`\u2014 ${option.hint}`)}` : "";
|
|
110
|
-
lines.push(` ${ansi.dim(FLOW_PIPE)}
|
|
114
|
+
lines.push(` ${ansi.dim(FLOW_PIPE)} ${activeMark} ${selectedMark} ${value}${hint}`);
|
|
111
115
|
}
|
|
112
116
|
if (filtered.length > maxVisible) {
|
|
113
117
|
lines.push(` ${ansi.dim(FLOW_PIPE)} ${ansi.dim(`${filtered.length} options`)}`);
|
|
@@ -217,16 +221,26 @@ async function promptText(opts) {
|
|
|
217
221
|
const question = ` ${ansi.cyan("\u25C6")} ${opts.message}${opts.placeholder ? ` ${ansi.dim(`(${opts.placeholder})`)}` : ""}: `;
|
|
218
222
|
const previousRawMode = stdin.isRaw;
|
|
219
223
|
if (previousRawMode) stdin.setRawMode(false);
|
|
224
|
+
const ABORTED = /* @__PURE__ */ Symbol("aborted");
|
|
220
225
|
const value = await new Promise((resolve) => {
|
|
221
226
|
rl.on("SIGINT", () => resolve(null));
|
|
222
227
|
rl.question(question, (answer) => resolve(answer));
|
|
228
|
+
if (opts.abortSignal) {
|
|
229
|
+
const onAbort = () => resolve(ABORTED);
|
|
230
|
+
if (opts.abortSignal.aborted) {
|
|
231
|
+
onAbort();
|
|
232
|
+
} else {
|
|
233
|
+
opts.abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
234
|
+
}
|
|
235
|
+
}
|
|
223
236
|
});
|
|
224
237
|
rl.close();
|
|
225
238
|
restoreKeypressListeners();
|
|
226
239
|
if (previousRawMode) stdin.setRawMode(true);
|
|
227
|
-
if (opts.clearAfterSubmit) {
|
|
240
|
+
if (opts.clearAfterSubmit || value === ABORTED) {
|
|
228
241
|
clearRenderedLines(2);
|
|
229
242
|
}
|
|
243
|
+
if (value === ABORTED) return "";
|
|
230
244
|
if (value === null) {
|
|
231
245
|
printCancel(opts.cancelMessage);
|
|
232
246
|
return null;
|
|
@@ -281,6 +295,7 @@ async function promptMultiselect(opts) {
|
|
|
281
295
|
const result = await runListPrompt({
|
|
282
296
|
message: opts.message,
|
|
283
297
|
options: opts.options,
|
|
298
|
+
initialValues: opts.initialValues,
|
|
284
299
|
allowMultiple: true,
|
|
285
300
|
required: opts.required,
|
|
286
301
|
commitLabel: "Selected"
|
|
@@ -362,29 +377,24 @@ async function withSpinner(label, doneLabel, fn) {
|
|
|
362
377
|
if (isJSONMode() || quiet) return fn();
|
|
363
378
|
return runWithSpinner(label, doneLabel, fn);
|
|
364
379
|
}
|
|
365
|
-
function
|
|
380
|
+
function printKeyValue(pairs, withBottomPadding = true) {
|
|
366
381
|
if (isJSONMode()) return;
|
|
382
|
+
console.log("");
|
|
367
383
|
if (pairs.length === 0) {
|
|
368
|
-
|
|
369
|
-
|
|
384
|
+
if (withBottomPadding) {
|
|
385
|
+
console.log("");
|
|
386
|
+
}
|
|
370
387
|
return;
|
|
371
388
|
}
|
|
372
|
-
const
|
|
373
|
-
const
|
|
389
|
+
const maxLen = Math.max(...pairs.map(([k]) => stripAnsi(k).length));
|
|
390
|
+
for (const [key, value] of pairs) {
|
|
374
391
|
const visibleKeyLen = stripAnsi(key).length;
|
|
375
|
-
const paddedKey = key + " ".repeat(Math.max(0,
|
|
376
|
-
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
const bottom = `\u2514${"\u2500".repeat(contentWidth + 2)}\u2518`;
|
|
381
|
-
console.log(` ${ansi2.dim(top)}`);
|
|
382
|
-
for (const row of contentRows) {
|
|
383
|
-
const visibleLen = stripAnsi(row).length;
|
|
384
|
-
const padded = row + " ".repeat(Math.max(0, contentWidth - visibleLen));
|
|
385
|
-
console.log(` ${ansi2.dim("\u2502")} ${padded} ${ansi2.dim("\u2502")}`);
|
|
392
|
+
const paddedKey = key + " ".repeat(Math.max(0, maxLen - visibleKeyLen));
|
|
393
|
+
console.log(` ${ansi2.dim(paddedKey)} ${value}`);
|
|
394
|
+
}
|
|
395
|
+
if (withBottomPadding) {
|
|
396
|
+
console.log("");
|
|
386
397
|
}
|
|
387
|
-
console.log(` ${ansi2.dim(bottom)}`);
|
|
388
398
|
}
|
|
389
399
|
function emptyState(message) {
|
|
390
400
|
if (isJSONMode()) return;
|
|
@@ -543,7 +553,7 @@ export {
|
|
|
543
553
|
successBadge,
|
|
544
554
|
failBadge,
|
|
545
555
|
withSpinner,
|
|
546
|
-
|
|
556
|
+
printKeyValue,
|
|
547
557
|
emptyState,
|
|
548
558
|
printSyntaxJSON,
|
|
549
559
|
printTable,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
|
|
3
3
|
import {
|
|
4
4
|
isRevealMode
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-QEDAULQ2.js";
|
|
6
6
|
|
|
7
7
|
// src/lib/secrets.ts
|
|
8
8
|
function maskSecret(value) {
|
|
@@ -35,7 +35,23 @@ var KEY_MAP = {
|
|
|
35
35
|
"auth-token": "auth_token",
|
|
36
36
|
auth_token: "auth_token",
|
|
37
37
|
"auth-token-expires-at": "auth_token_expires_at",
|
|
38
|
-
auth_token_expires_at: "auth_token_expires_at"
|
|
38
|
+
auth_token_expires_at: "auth_token_expires_at",
|
|
39
|
+
"solana-wallet-key-file": "solana_wallet_key_file",
|
|
40
|
+
solana_wallet_key_file: "solana_wallet_key_file",
|
|
41
|
+
"solana-wallet-address": "solana_wallet_address",
|
|
42
|
+
solana_wallet_address: "solana_wallet_address",
|
|
43
|
+
"evm-gas-sponsored": "evm_gas_sponsored",
|
|
44
|
+
evm_gas_sponsored: "evm_gas_sponsored",
|
|
45
|
+
"evm-gas-policy-id": "evm_gas_policy_id",
|
|
46
|
+
evm_gas_policy_id: "evm_gas_policy_id",
|
|
47
|
+
"solana-fee-sponsored": "solana_fee_sponsored",
|
|
48
|
+
solana_fee_sponsored: "solana_fee_sponsored",
|
|
49
|
+
"solana-fee-policy-id": "solana_fee_policy_id",
|
|
50
|
+
solana_fee_policy_id: "solana_fee_policy_id",
|
|
51
|
+
"delegated-wallet": "delegated_wallet",
|
|
52
|
+
delegated_wallet: "delegated_wallet",
|
|
53
|
+
"active-signer": "active_signer",
|
|
54
|
+
active_signer: "active_signer"
|
|
39
55
|
};
|
|
40
56
|
var SAFE_ID_RE = /^[A-Za-z0-9:_-]{1,128}$/;
|
|
41
57
|
var SAFE_NETWORK_RE = /^[A-Za-z0-9:_-]{1,128}$/;
|
|
@@ -63,7 +79,15 @@ var configSchema = z.object({
|
|
|
63
79
|
auth_token: safeTextSchema(MAX_SECRET_LEN).optional().catch(void 0),
|
|
64
80
|
auth_token_expires_at: safeTextSchema(MAX_SECRET_LEN).optional().catch(void 0),
|
|
65
81
|
siwe_token: safeTextSchema(MAX_PATH_LEN).optional().catch(void 0),
|
|
66
|
-
siwe_token_expires_at: safeTextSchema(MAX_SECRET_LEN).optional().catch(void 0)
|
|
82
|
+
siwe_token_expires_at: safeTextSchema(MAX_SECRET_LEN).optional().catch(void 0),
|
|
83
|
+
solana_wallet_key_file: safeTextSchema(MAX_PATH_LEN).optional().catch(void 0),
|
|
84
|
+
solana_wallet_address: safeTextSchema(MAX_SECRET_LEN).optional().catch(void 0),
|
|
85
|
+
evm_gas_sponsored: z.boolean().optional().catch(void 0),
|
|
86
|
+
evm_gas_policy_id: safeTextSchema(MAX_SECRET_LEN).optional().catch(void 0),
|
|
87
|
+
solana_fee_sponsored: z.boolean().optional().catch(void 0),
|
|
88
|
+
solana_fee_policy_id: safeTextSchema(MAX_SECRET_LEN).optional().catch(void 0),
|
|
89
|
+
delegated_wallet: z.boolean().optional().catch(void 0),
|
|
90
|
+
active_signer: z.enum(["session", "local"]).optional().catch(void 0)
|
|
67
91
|
}).strip();
|
|
68
92
|
function sanitizeConfig(input) {
|
|
69
93
|
const parsed = configSchema.safeParse(input);
|
|
@@ -72,6 +96,13 @@ function sanitizeConfig(input) {
|
|
|
72
96
|
}
|
|
73
97
|
return parsed.data;
|
|
74
98
|
}
|
|
99
|
+
function applyLegacyMigration(cfg) {
|
|
100
|
+
if (cfg.active_signer === void 0 && cfg.delegated_wallet === true) {
|
|
101
|
+
const { delegated_wallet: _, ...rest } = cfg;
|
|
102
|
+
return { ...rest, active_signer: "session" };
|
|
103
|
+
}
|
|
104
|
+
return cfg;
|
|
105
|
+
}
|
|
75
106
|
function getHome() {
|
|
76
107
|
return process.env.HOME || homedir();
|
|
77
108
|
}
|
|
@@ -88,7 +119,7 @@ function load() {
|
|
|
88
119
|
if (!existsSync(p)) return {};
|
|
89
120
|
try {
|
|
90
121
|
const data = readFileSync(p, "utf-8");
|
|
91
|
-
return sanitizeConfig(JSON.parse(data));
|
|
122
|
+
return applyLegacyMigration(sanitizeConfig(JSON.parse(data)));
|
|
92
123
|
} catch {
|
|
93
124
|
console.error(`warning: could not parse config file at ${p} \u2014 using defaults`);
|
|
94
125
|
return {};
|
|
@@ -97,6 +128,7 @@ function load() {
|
|
|
97
128
|
function save(cfg) {
|
|
98
129
|
const p = configPath();
|
|
99
130
|
const sanitized = sanitizeConfig(cfg);
|
|
131
|
+
delete sanitized.delegated_wallet;
|
|
100
132
|
mkdirSync(dirname(p), { recursive: true, mode: 493 });
|
|
101
133
|
writeFileSync(p, JSON.stringify(sanitized, null, 2) + "\n", {
|
|
102
134
|
mode: 384
|
|
@@ -115,6 +147,21 @@ function get(cfg, key) {
|
|
|
115
147
|
if (typeof value === "string") return value;
|
|
116
148
|
return void 0;
|
|
117
149
|
}
|
|
150
|
+
function validKeys() {
|
|
151
|
+
return [
|
|
152
|
+
"api-key",
|
|
153
|
+
"access-key",
|
|
154
|
+
"webhook-api-key",
|
|
155
|
+
"network",
|
|
156
|
+
"verbose",
|
|
157
|
+
"wallet-key-file",
|
|
158
|
+
"x402",
|
|
159
|
+
"evm-gas-sponsored",
|
|
160
|
+
"evm-gas-policy-id",
|
|
161
|
+
"solana-fee-sponsored",
|
|
162
|
+
"solana-fee-policy-id"
|
|
163
|
+
];
|
|
164
|
+
}
|
|
118
165
|
function toMap(cfg) {
|
|
119
166
|
const m = {};
|
|
120
167
|
if (cfg.api_key) m["api-key"] = maskIf(cfg.api_key);
|
|
@@ -128,6 +175,13 @@ function toMap(cfg) {
|
|
|
128
175
|
if (cfg.x402 !== void 0) m["x402"] = String(cfg.x402);
|
|
129
176
|
if (cfg.auth_token) m["auth-token"] = maskIf(cfg.auth_token);
|
|
130
177
|
if (cfg.auth_token_expires_at) m["auth-token-expires-at"] = cfg.auth_token_expires_at;
|
|
178
|
+
if (cfg.solana_wallet_key_file) m["solana-wallet-key-file"] = cfg.solana_wallet_key_file;
|
|
179
|
+
if (cfg.solana_wallet_address) m["solana-wallet-address"] = cfg.solana_wallet_address;
|
|
180
|
+
if (cfg.evm_gas_sponsored !== void 0) m["evm-gas-sponsored"] = String(cfg.evm_gas_sponsored);
|
|
181
|
+
if (cfg.evm_gas_policy_id) m["evm-gas-policy-id"] = cfg.evm_gas_policy_id;
|
|
182
|
+
if (cfg.solana_fee_sponsored !== void 0) m["solana-fee-sponsored"] = String(cfg.solana_fee_sponsored);
|
|
183
|
+
if (cfg.solana_fee_policy_id) m["solana-fee-policy-id"] = cfg.solana_fee_policy_id;
|
|
184
|
+
if (cfg.active_signer !== void 0) m["active-signer"] = cfg.active_signer;
|
|
131
185
|
return m;
|
|
132
186
|
}
|
|
133
187
|
|
|
@@ -139,5 +193,6 @@ export {
|
|
|
139
193
|
load,
|
|
140
194
|
save,
|
|
141
195
|
get,
|
|
196
|
+
validKeys,
|
|
142
197
|
toMap
|
|
143
198
|
};
|