@alchemy/cli 0.7.0-alpha.5 → 0.7.1
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 +75 -43
- package/dist/{auth-I5WFLU46.js → auth-BNT5Z5GZ.js} +4 -4
- package/dist/auth-JGON2JU6.js +0 -0
- package/dist/{chunk-A6L3WCJN.js → chunk-5IFXLC2S.js} +68 -8
- package/dist/{chunk-B3R6PRAL.js → chunk-7WD3YLRK.js} +65 -2
- package/dist/chunk-HSKKIATB.js +0 -0
- package/dist/chunk-HYCRHNPX.js +0 -0
- package/dist/chunk-QEDAULQ2.js +0 -0
- package/dist/{chunk-5MXODL63.js → chunk-RS3DSL3X.js} +2 -2
- package/dist/{chunk-NT3G6BKD.js → chunk-SYP6KKP6.js} +3 -3
- package/dist/{chunk-PKAN5FKD.js → chunk-TOEVZMIP.js} +4 -2
- package/dist/{chunk-MUT4TFQ5.js → chunk-V4IK4CJN.js} +2 -2
- package/dist/errors-3CNFGAXT.js +0 -0
- package/dist/index.js +135 -40
- package/dist/{interactive-VXPD6N7Z.js → interactive-N33RCX33.js} +8 -5
- package/dist/{onboarding-CEHXSNYD.js → onboarding-S6HKWOEA.js} +4 -4
- package/dist/{resolve-X7HLVLGA.js → resolve-R4JZZCCF.js} +2 -2
- package/package.json +25 -23
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Alchemy CLI is a command-line tool for querying blockchain data and managing Alchemy apps/configuration.
|
|
4
4
|
It supports both human-friendly terminal output and JSON output for automation.
|
|
5
|
-
You can use API keys, access keys, or x402 wallet auth depending on the command.
|
|
5
|
+
You can use browser login, API keys, access keys, or x402 wallet auth depending on the command.
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
@@ -51,7 +51,7 @@ If you run `alchemy` with no command and no auth configured, the CLI will guide
|
|
|
51
51
|
|
|
52
52
|
If you have an auth token but haven't selected an app yet, the CLI will prompt you to pick one before running any command that requires an API key. Teams with many apps can type to search by name.
|
|
53
53
|
|
|
54
|
-
If you use Notify webhooks, add webhook auth on top via `alchemy config set webhook-api-key <key>`, `--webhook-api-key
|
|
54
|
+
If you use Notify webhooks, add webhook auth on top via `alchemy config set webhook-api-key <key>`, `--webhook-api-key` on `alchemy webhook` commands, or `ALCHEMY_WEBHOOK_API_KEY`.
|
|
55
55
|
|
|
56
56
|
### Usage By Workflow
|
|
57
57
|
|
|
@@ -79,10 +79,10 @@ Have your agent run `agent-prompt` as its first step to get a complete, machine-
|
|
|
79
79
|
|
|
80
80
|
```bash
|
|
81
81
|
# Agent runs this once to learn everything the CLI can do
|
|
82
|
-
alchemy --json agent-prompt
|
|
82
|
+
alchemy --json --no-interactive agent-prompt
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
-
This returns a single JSON document with execution policy, preflight instructions, auth matrix, the full command tree with all arguments and options, error codes with recovery actions, and example invocations. No external docs required.
|
|
85
|
+
This returns a single JSON document with execution policy, runtime discovery instructions, preflight instructions, auth matrix, the full command tree with all arguments and options, error codes with recovery actions, and example invocations. No external docs required.
|
|
86
86
|
|
|
87
87
|
Agents can also call `alchemy --json --no-interactive update-check` to retrieve the current CLI version, latest known version, and install command for upgrades.
|
|
88
88
|
|
|
@@ -114,24 +114,21 @@ Use `alchemy help` or `alchemy help <command>` for generated command help.
|
|
|
114
114
|
|
|
115
115
|
### Wallets
|
|
116
116
|
|
|
117
|
-
`alchemy
|
|
117
|
+
`alchemy wallet` 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.
|
|
118
118
|
|
|
119
119
|
| Command | What it does | Example |
|
|
120
120
|
|---|---|---|
|
|
121
|
-
| `
|
|
122
|
-
| `
|
|
123
|
-
| `
|
|
124
|
-
| `
|
|
125
|
-
| `
|
|
126
|
-
| `
|
|
127
|
-
| `
|
|
128
|
-
| `
|
|
121
|
+
| `wallet connect` | Interactive: choose a session wallet (recommended) or a local wallet. For scripts, pass `--mode <session\|local>`. | `alchemy wallet connect` |
|
|
122
|
+
| `wallet connect --mode local --chain evm` | Create a new local EVM key (non-interactive). `--chain` accepts `evm`, `solana`, or `both`. | `alchemy wallet connect --mode local --chain both` |
|
|
123
|
+
| `wallet connect --mode local --import <path>` | Import an existing EVM private key from a file. | `alchemy wallet connect --mode local --import ./key.txt` |
|
|
124
|
+
| `wallet connect --mode session --instance-name <name>` | Connect a named session wallet instance. | `alchemy wallet connect --mode session --instance-name laptop` |
|
|
125
|
+
| `wallet status [--verify]` | Reports session, local EVM, local Solana, and the active signer. `--verify` reconciles the session with the backend. | `alchemy wallet status --verify` |
|
|
126
|
+
| `wallet address` | Prints addresses for every configured signer. | `alchemy wallet address` |
|
|
127
|
+
| `wallet use <session\|local>` | Selects which signer `evm send`, `evm swap`, `evm approve`, `xchain bridge`, and `evm contract call` use for EVM transactions. | `alchemy wallet use local` |
|
|
128
|
+
| `wallet disconnect` | Revokes the current session (local + backend). Clears `active_signer` if it pointed at the session. | `alchemy wallet disconnect` |
|
|
129
|
+
| `wallet qr [--type <evm\|solana>]` | Renders a configured address as a QR code. | `alchemy wallet qr --type evm` |
|
|
129
130
|
|
|
130
131
|
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.
|
|
131
|
-
| `webhooks list` | Lists Notify webhooks | `alchemy webhooks list --webhook-api-key <key>` |
|
|
132
|
-
| `webhooks create --body <json>` | Creates Notify webhook | `alchemy webhooks create --body '{...}' --webhook-api-key <key>` |
|
|
133
|
-
| `webhooks update --body <json>` | Updates Notify webhook | `alchemy webhooks update --body '{...}' --webhook-api-key <key>` |
|
|
134
|
-
| `webhooks delete <id>` | Deletes Notify webhook | `alchemy webhooks delete <id> --webhook-api-key <key>` |
|
|
135
132
|
|
|
136
133
|
### Chains
|
|
137
134
|
|
|
@@ -140,6 +137,10 @@ Per-command override: pass `--signer <session\|local>` to `evm send`, `evm appro
|
|
|
140
137
|
| `solana rpc <method> [params...]` | Calls Solana JSON-RPC methods | `alchemy solana rpc getBalance '"<pubkey>"'` |
|
|
141
138
|
| `solana das <method> [params...]` | Calls Solana DAS methods | `alchemy solana das getAssetsByOwner '{"ownerAddress":"<pubkey>"}'` |
|
|
142
139
|
| `solana network list` | Lists networks from the Solana namespace | `alchemy solana network list --search solana` |
|
|
140
|
+
| `solana send <to> <amount>` | Sends SOL to an address | `alchemy solana send <pubkey> 0.1` |
|
|
141
|
+
| `solana program accounts/account/show` | Inspects Solana program accounts and account metadata | `alchemy solana program accounts <program-id>` |
|
|
142
|
+
| `solana delegate approve/revoke` | Approves or revokes SPL token delegates | `alchemy solana delegate approve --token-account <addr> --mint <mint> --delegate <addr> --amount 1 --decimals 6` |
|
|
143
|
+
| `solana status [id]` | Checks Solana transaction or operation status | `alchemy solana status <signature>` |
|
|
143
144
|
| `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` |
|
|
144
145
|
|
|
145
146
|
### CLI Admin
|
|
@@ -150,26 +151,34 @@ Per-command override: pass `--signer <session\|local>` to `evm send`, `evm appro
|
|
|
150
151
|
| `auth` (`auth login`) | Log in via browser (PKCE) | `alchemy auth` |
|
|
151
152
|
| `auth status` | Show current authentication status | `alchemy auth status` |
|
|
152
153
|
| `auth logout` | Clear saved authentication token | `alchemy auth logout` |
|
|
153
|
-
| `
|
|
154
|
-
| `
|
|
155
|
-
| `
|
|
156
|
-
| `
|
|
157
|
-
| `
|
|
158
|
-
| `
|
|
159
|
-
| `
|
|
160
|
-
| `
|
|
161
|
-
| `
|
|
162
|
-
| `
|
|
154
|
+
| `app list` | Lists apps (supports pagination/filtering) | `alchemy app list --all` |
|
|
155
|
+
| `app chains` | Lists Admin API chain identifiers (e.g. `ETH_MAINNET`) | `alchemy app chains` |
|
|
156
|
+
| `app get <id>` | Gets app details | `alchemy app get <app-id>` |
|
|
157
|
+
| `app create` | Creates app | `alchemy app create --name "My App" --networks eth-mainnet` |
|
|
158
|
+
| `app update <id>` | Updates app name/description | `alchemy app update <app-id> --name "New Name"` |
|
|
159
|
+
| `app delete <id>` | Deletes app | `alchemy app delete <app-id>` |
|
|
160
|
+
| `app networks <id>` | Updates app network allowlist | `alchemy app networks <app-id> --networks eth-mainnet,polygon-mainnet` |
|
|
161
|
+
| `app address-allowlist <id>` | Updates app address allowlist | `alchemy app address-allowlist <app-id> --addresses 0xabc,0xdef` |
|
|
162
|
+
| `app origin-allowlist <id>` | Updates app origin allowlist | `alchemy app origin-allowlist <app-id> --origins https://example.com` |
|
|
163
|
+
| `app ip-allowlist <id>` | Updates app IP allowlist | `alchemy app ip-allowlist <app-id> --ips 1.2.3.4,5.6.7.8` |
|
|
164
|
+
| `app configured-networks` | Lists RPC network slugs configured for an app | `alchemy app configured-networks --app-id <app-id>` |
|
|
165
|
+
| `app select [id]` | Selects the default app interactively or by ID | `alchemy app select <app-id>` |
|
|
166
|
+
| `webhook list` | Lists Notify webhooks | `alchemy webhook list --webhook-api-key <key>` |
|
|
167
|
+
| `webhook create --body <json>` | Creates Notify webhook | `alchemy webhook create --body '{...}' --webhook-api-key <key>` |
|
|
168
|
+
| `webhook update --body <json>` | Updates Notify webhook | `alchemy webhook update --body '{...}' --webhook-api-key <key>` |
|
|
169
|
+
| `webhook delete <id>` | Deletes Notify webhook | `alchemy webhook delete <id> --webhook-api-key <key>` |
|
|
170
|
+
| `webhook addresses <id>` | Gets address activity webhook addresses | `alchemy webhook addresses <id> --webhook-api-key <key>` |
|
|
171
|
+
| `webhook nft-filters <id>` | Gets NFT activity webhook filters | `alchemy webhook nft-filters <id> --webhook-api-key <key>` |
|
|
163
172
|
| `doctor` | Runs readiness checks and suggestions | `alchemy doctor` |
|
|
164
173
|
| `install mcp` | Installs Alchemy's remote MCP server config | `alchemy install mcp --client claude --dry-run` |
|
|
165
174
|
| `install skills` | Installs bundled Alchemy skills | `alchemy install skills --client cursor --dry-run` |
|
|
166
175
|
| `update-check` | Checks whether a newer CLI version is available | `alchemy update-check --json --no-interactive` |
|
|
167
|
-
| `config set ...` | Sets config values | `alchemy config set
|
|
176
|
+
| `config set ...` | Sets config values | `alchemy config set app <app-id>` |
|
|
168
177
|
| `config get <key>` | Gets one config value | `alchemy config get network` |
|
|
169
178
|
| `config list` | Lists all config values | `alchemy config list` |
|
|
170
179
|
| `config reset [key]` | Resets one or all config values | `alchemy config reset --yes` |
|
|
171
180
|
| `completions <shell>` | Generates shell completion scripts (bash/zsh/fish) | `eval "$(alchemy completions zsh)"` |
|
|
172
|
-
| `agent-prompt` | Emits complete agent/automation usage instructions | `alchemy --json agent-prompt` |
|
|
181
|
+
| `agent-prompt` | Emits complete agent/automation usage instructions | `alchemy --json --no-interactive agent-prompt` |
|
|
173
182
|
| `version` | Prints CLI version | `alchemy version` |
|
|
174
183
|
|
|
175
184
|
## Flags
|
|
@@ -183,10 +192,10 @@ These apply to all commands.
|
|
|
183
192
|
| Flag | Env var | Description |
|
|
184
193
|
|---|---|---|
|
|
185
194
|
| `--api-key <key>` | `ALCHEMY_API_KEY` | API key for blockchain query commands |
|
|
186
|
-
| `--access-key <key>` | `ALCHEMY_ACCESS_KEY` | Access key for Admin API operations |
|
|
187
195
|
| `-n, --network <network>` | `ALCHEMY_NETWORK` | Target network (default: `eth-mainnet`) |
|
|
188
196
|
| `--x402` | — | Enable x402 wallet-based gateway auth |
|
|
189
|
-
| `--wallet-key-file <path>` | — |
|
|
197
|
+
| `--wallet-key-file <path>` | — | EVM wallet private key file for x402 auth and local signing |
|
|
198
|
+
| `--solana-wallet-key-file <path>` | — | Solana wallet private key file for local signing |
|
|
190
199
|
|
|
191
200
|
#### Output & formatting
|
|
192
201
|
|
|
@@ -211,7 +220,14 @@ Additional env vars:
|
|
|
211
220
|
| Env var | Description |
|
|
212
221
|
|---|---|
|
|
213
222
|
| `ALCHEMY_CONFIG` | Custom path to config file |
|
|
214
|
-
| `
|
|
223
|
+
| `ALCHEMY_ACCESS_KEY` | Access key for Admin API operations |
|
|
224
|
+
| `ALCHEMY_WALLET_KEY` | EVM wallet private key for x402 auth and local signing |
|
|
225
|
+
| `ALCHEMY_SOLANA_WALLET_KEY` | Solana wallet private key |
|
|
226
|
+
| `ALCHEMY_ACTIVE_SIGNER` | Active EVM signer override (`session` or `local`) |
|
|
227
|
+
| `ALCHEMY_EVM_GAS_SPONSORED` | Enable EVM gas sponsorship when set to `true` |
|
|
228
|
+
| `ALCHEMY_EVM_GAS_POLICY_ID` | EVM gas sponsorship policy ID |
|
|
229
|
+
| `ALCHEMY_SOLANA_FEE_SPONSORED` | Enable Solana fee sponsorship when set to `true` |
|
|
230
|
+
| `ALCHEMY_SOLANA_FEE_POLICY_ID` | Solana fee sponsorship policy ID |
|
|
215
231
|
| `ALCHEMY_WEBHOOK_API_KEY` | Webhook API key for Notify commands |
|
|
216
232
|
|
|
217
233
|
### Command-specific flags
|
|
@@ -228,18 +244,34 @@ Additional env vars:
|
|
|
228
244
|
| `evm data price historical` | `--body <json>` (required) |
|
|
229
245
|
| `evm data portfolio *` | `--body <json>` (required per subcommand) |
|
|
230
246
|
| `evm simulate *` | `--tx <json>` or `--txs <json>` (required) |
|
|
231
|
-
| `
|
|
232
|
-
| `
|
|
233
|
-
| `
|
|
234
|
-
| `
|
|
235
|
-
| `
|
|
236
|
-
| `
|
|
237
|
-
| `
|
|
238
|
-
| `
|
|
239
|
-
| `
|
|
247
|
+
| `evm send` | `--token <address>`, `--gas-sponsored`, `--gas-policy-id <id>`, `--signer <session\|local>` |
|
|
248
|
+
| `evm contract call` | `--args <json>`, `--abi-file <path>`, `--abi <json>`, `--value <ether>`, `--gas-sponsored`, `--gas-policy-id <id>`, `--signer <session\|local>` |
|
|
249
|
+
| `evm swap quote` | `--from <token_address>`, `--to <token_address>`, `--amount <number>`, `--slippage <percent>`, `--signer <session\|local>` |
|
|
250
|
+
| `evm swap execute` | `--from <token_address>`, `--to <token_address>`, `--amount <number>`, `--slippage <percent>`, `--gas-sponsored`, `--gas-policy-id <id>`, `--signer <session\|local>` |
|
|
251
|
+
| `evm approve` | `--token-address <token_address>`, `--amount <decimal_amount>`, `--unlimited`, `--revoke`, `--reset-first`, `-y, --yes`, `--gas-sponsored`, `--gas-policy-id <id>`, `--signer <session\|local>` |
|
|
252
|
+
| `xchain bridge quote` | `--from <token_address>`, `--to <token_address>`, `--amount <number>`, `--to-network <network>`, `--slippage <percent>`, `--signer <session\|local>` |
|
|
253
|
+
| `xchain bridge execute` | `--from <token_address>`, `--to <token_address>`, `--amount <number>`, `--to-network <network>`, `--slippage <percent>`, `--gas-sponsored`, `--gas-policy-id <id>`, `--signer <session\|local>` |
|
|
254
|
+
| `wallet connect` | `--mode <session\|local>`, `--chain <evm\|solana\|both>`, `--import <path>`, `--instance-name <name>`, `--force` |
|
|
255
|
+
| `wallet status` | `--verify` |
|
|
256
|
+
| `wallet qr` | `--type <evm\|solana>`, `--solana` |
|
|
257
|
+
| `solana send` | `--fee-sponsored`, `--fee-policy-id <id>`, `--signer <local>` (session signing is not yet supported for Solana) |
|
|
258
|
+
| `solana program accounts` | `--filters <json>`, `--encoding <encoding>`, `--limit <n>` |
|
|
259
|
+
| `solana delegate approve` | `--token-account <address>`, `--mint <address>`, `--delegate <address>`, `--amount <number>`, `--decimals <n>`, `--fee-sponsored`, `--fee-policy-id <id>` |
|
|
260
|
+
| `solana delegate revoke` | `--token-account <address>`, `--fee-sponsored`, `--fee-policy-id <id>` |
|
|
261
|
+
| `webhook *` | `--webhook-api-key <key>` (or `ALCHEMY_WEBHOOK_API_KEY`, `ALCHEMY_NOTIFY_AUTH_TOKEN`, config `webhook-api-key`, or app webhook key) |
|
|
262
|
+
| `app list` | `--cursor <cursor>`, `--limit <n>`, `--all`, `--search <query>`, `--id <appId>` |
|
|
263
|
+
| `app create` | `--name <name>` (required), `--networks <networks>` (required), `--description <desc>`, `--products <products>`, `--dry-run` |
|
|
264
|
+
| `app update` | `--name <name>`, `--description <desc>`, `--dry-run` |
|
|
265
|
+
| `app delete` | `--dry-run`, `-y, --yes` |
|
|
266
|
+
| `app networks` | `--networks <networks>` (required), `--dry-run` |
|
|
267
|
+
| `app address-allowlist` | `--addresses <addrs>` (required), `--dry-run` |
|
|
268
|
+
| `app origin-allowlist` | `--origins <origins>` (required), `--dry-run` |
|
|
269
|
+
| `app ip-allowlist` | `--ips <ips>` (required), `--dry-run` |
|
|
270
|
+
| `app configured-networks` | `--app-id <id>` |
|
|
240
271
|
| `install mcp` | `--client <claude,cursor,codex,other,all>`, `--dry-run` |
|
|
241
272
|
| `install skills` | `--client <claude,cursor,codex,all>`, `--dry-run` |
|
|
242
273
|
| `evm network list` | `--mainnet-only`, `--testnet-only`, `--search <term>` |
|
|
274
|
+
| `config set` | `webhook-api-key`, `app`, `network`, `verbose`, `wallet-key-file`, `x402`, `evm-gas-sponsored`, `evm-gas-policy-id`, `solana-fee-sponsored`, `solana-fee-policy-id` |
|
|
243
275
|
| `config reset` | `-y, --yes` |
|
|
244
276
|
|
|
245
277
|
## Authentication Reference
|
|
@@ -294,8 +326,8 @@ Errors are structured JSON in JSON mode:
|
|
|
294
326
|
{
|
|
295
327
|
"error": {
|
|
296
328
|
"code": "AUTH_REQUIRED",
|
|
297
|
-
"message": "Not authenticated.
|
|
298
|
-
"hint": "alchemy
|
|
329
|
+
"message": "Not authenticated. Run 'alchemy auth' to log in, or set ALCHEMY_API_KEY.",
|
|
330
|
+
"hint": "alchemy auth"
|
|
299
331
|
}
|
|
300
332
|
}
|
|
301
333
|
```
|
|
@@ -3,12 +3,12 @@ if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
|
|
|
3
3
|
import {
|
|
4
4
|
registerAuth,
|
|
5
5
|
selectAppAfterAuth
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-SYP6KKP6.js";
|
|
7
7
|
import "./chunk-HSKKIATB.js";
|
|
8
8
|
import "./chunk-HYCRHNPX.js";
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-TOEVZMIP.js";
|
|
10
|
+
import "./chunk-5IFXLC2S.js";
|
|
11
|
+
import "./chunk-7WD3YLRK.js";
|
|
12
12
|
import "./chunk-QEDAULQ2.js";
|
|
13
13
|
export {
|
|
14
14
|
registerAuth,
|
package/dist/auth-JGON2JU6.js
CHANGED
|
File without changes
|
|
@@ -46,6 +46,53 @@ function suspendStdinKeypressListeners() {
|
|
|
46
46
|
}
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
|
+
function resetStdinKeypressDecoder() {
|
|
50
|
+
const input = stdin;
|
|
51
|
+
for (const symbol of Object.getOwnPropertySymbols(input)) {
|
|
52
|
+
const name = String(symbol);
|
|
53
|
+
if (name === "Symbol(keypress-decoder)" || name === "Symbol(escape-decoder)") {
|
|
54
|
+
delete input[symbol];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function isReadlineKeypressDataListener(listener) {
|
|
59
|
+
return typeof listener === "function" && listener.name === "onData";
|
|
60
|
+
}
|
|
61
|
+
function prepareStdinKeypressEvents() {
|
|
62
|
+
const dataListeners = stdin.listeners("data");
|
|
63
|
+
const keypressListeners = stdin.listeners("keypress");
|
|
64
|
+
for (const listener of dataListeners) {
|
|
65
|
+
stdin.removeListener("data", listener);
|
|
66
|
+
}
|
|
67
|
+
for (const listener of keypressListeners) {
|
|
68
|
+
stdin.removeListener("keypress", listener);
|
|
69
|
+
}
|
|
70
|
+
resetStdinKeypressDecoder();
|
|
71
|
+
readline.emitKeypressEvents(stdin);
|
|
72
|
+
return () => {
|
|
73
|
+
for (const listener of stdin.listeners("data")) {
|
|
74
|
+
stdin.removeListener("data", listener);
|
|
75
|
+
}
|
|
76
|
+
resetStdinKeypressDecoder();
|
|
77
|
+
for (const listener of dataListeners) {
|
|
78
|
+
if (!isReadlineKeypressDataListener(listener)) {
|
|
79
|
+
stdin.on("data", listener);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
for (const listener of keypressListeners) {
|
|
83
|
+
stdin.on("keypress", listener);
|
|
84
|
+
}
|
|
85
|
+
if (keypressListeners.length > 0) {
|
|
86
|
+
readline.emitKeypressEvents(stdin);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function requestPromptInterrupt() {
|
|
91
|
+
const handled = process.emit("SIGINT", "SIGINT");
|
|
92
|
+
if (!handled) {
|
|
93
|
+
process.exit(130);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
49
96
|
async function runListPrompt(opts) {
|
|
50
97
|
if (!stdin.isTTY || !stdout.isTTY) {
|
|
51
98
|
if (opts.allowMultiple) {
|
|
@@ -54,8 +101,7 @@ async function runListPrompt(opts) {
|
|
|
54
101
|
const initial = opts.initialValue ?? opts.options.find((o) => !o.disabled)?.value ?? null;
|
|
55
102
|
return { value: initial, cancelled: false };
|
|
56
103
|
}
|
|
57
|
-
|
|
58
|
-
const restoreKeypressListeners = suspendStdinKeypressListeners();
|
|
104
|
+
const restoreKeypressEvents = prepareStdinKeypressEvents();
|
|
59
105
|
const previousRawMode = stdin.isRaw;
|
|
60
106
|
stdin.resume();
|
|
61
107
|
stdin.setRawMode(true);
|
|
@@ -131,7 +177,7 @@ async function runListPrompt(opts) {
|
|
|
131
177
|
if (renderedLines > 0) clearRenderedLines(renderedLines);
|
|
132
178
|
stdin.setRawMode(previousRawMode);
|
|
133
179
|
stdin.removeListener("keypress", onKeypress);
|
|
134
|
-
|
|
180
|
+
restoreKeypressEvents();
|
|
135
181
|
if (!previousRawMode) {
|
|
136
182
|
stdin.pause();
|
|
137
183
|
}
|
|
@@ -144,7 +190,13 @@ async function runListPrompt(opts) {
|
|
|
144
190
|
const onKeypress = (str, key) => {
|
|
145
191
|
const filtered = getFiltered();
|
|
146
192
|
const current = filtered[cursor];
|
|
147
|
-
if (key.
|
|
193
|
+
if (key.ctrl && key.name === "c") {
|
|
194
|
+
cleanup();
|
|
195
|
+
requestPromptInterrupt();
|
|
196
|
+
resolver({ value: null, cancelled: true });
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
if (key.name === "escape") {
|
|
148
200
|
cleanup();
|
|
149
201
|
resolver({ value: null, cancelled: true });
|
|
150
202
|
return;
|
|
@@ -222,8 +274,10 @@ async function promptText(opts) {
|
|
|
222
274
|
const previousRawMode = stdin.isRaw;
|
|
223
275
|
if (previousRawMode) stdin.setRawMode(false);
|
|
224
276
|
const ABORTED = /* @__PURE__ */ Symbol("aborted");
|
|
277
|
+
const INTERRUPTED = /* @__PURE__ */ Symbol("interrupted");
|
|
278
|
+
let removeAbortListener;
|
|
225
279
|
const value = await new Promise((resolve) => {
|
|
226
|
-
rl.on("SIGINT", () => resolve(
|
|
280
|
+
rl.on("SIGINT", () => resolve(INTERRUPTED));
|
|
227
281
|
rl.question(question, (answer) => resolve(answer));
|
|
228
282
|
if (opts.abortSignal) {
|
|
229
283
|
const onAbort = () => resolve(ABORTED);
|
|
@@ -231,18 +285,24 @@ async function promptText(opts) {
|
|
|
231
285
|
onAbort();
|
|
232
286
|
} else {
|
|
233
287
|
opts.abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
288
|
+
removeAbortListener = () => opts.abortSignal?.removeEventListener("abort", onAbort);
|
|
234
289
|
}
|
|
235
290
|
}
|
|
236
291
|
});
|
|
237
292
|
rl.close();
|
|
293
|
+
removeAbortListener?.();
|
|
238
294
|
restoreKeypressListeners();
|
|
239
|
-
if (previousRawMode)
|
|
295
|
+
if (previousRawMode) {
|
|
296
|
+
stdin.setRawMode(true);
|
|
297
|
+
} else {
|
|
298
|
+
stdin.pause();
|
|
299
|
+
}
|
|
240
300
|
if (opts.clearAfterSubmit || value === ABORTED) {
|
|
241
301
|
clearRenderedLines(2);
|
|
242
302
|
}
|
|
243
303
|
if (value === ABORTED) return "";
|
|
244
|
-
if (value ===
|
|
245
|
-
|
|
304
|
+
if (value === INTERRUPTED) {
|
|
305
|
+
requestPromptInterrupt();
|
|
246
306
|
return null;
|
|
247
307
|
}
|
|
248
308
|
if (!value.trim() && opts.defaultValue !== void 0) return opts.defaultValue;
|
|
@@ -15,6 +15,7 @@ function maskIf(value) {
|
|
|
15
15
|
|
|
16
16
|
// src/lib/config.ts
|
|
17
17
|
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
|
|
18
|
+
import { createHash, randomUUID } from "crypto";
|
|
18
19
|
import { homedir } from "os";
|
|
19
20
|
import { join, dirname } from "path";
|
|
20
21
|
import { z } from "zod";
|
|
@@ -51,13 +52,18 @@ var KEY_MAP = {
|
|
|
51
52
|
"delegated-wallet": "delegated_wallet",
|
|
52
53
|
delegated_wallet: "delegated_wallet",
|
|
53
54
|
"active-signer": "active_signer",
|
|
54
|
-
active_signer: "active_signer"
|
|
55
|
+
active_signer: "active_signer",
|
|
56
|
+
"wallet-client-instance-name": "wallet_client_instance_name",
|
|
57
|
+
wallet_client_instance_name: "wallet_client_instance_name"
|
|
55
58
|
};
|
|
56
59
|
var SAFE_ID_RE = /^[A-Za-z0-9:_-]{1,128}$/;
|
|
57
60
|
var SAFE_NETWORK_RE = /^[A-Za-z0-9:_-]{1,128}$/;
|
|
61
|
+
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
58
62
|
var MAX_SECRET_LEN = 512;
|
|
59
63
|
var MAX_APP_NAME_LEN = 128;
|
|
64
|
+
var MAX_WALLET_CLIENT_INSTANCE_NAME_LEN = 64;
|
|
60
65
|
var CONTROL_CHAR_RE = /[\u0000-\u001f\u007f]/;
|
|
66
|
+
var WALLET_CLIENT_INSTANCE_ID_NAMESPACE = "alchemy-cli:wallet-client-instance-name:v1";
|
|
61
67
|
var safeTextSchema = (maxLen) => z.string().min(1).max(maxLen).refine((value) => !CONTROL_CHAR_RE.test(value));
|
|
62
68
|
var appConfigSchema = z.object({
|
|
63
69
|
id: z.string().regex(SAFE_ID_RE),
|
|
@@ -87,8 +93,13 @@ var configSchema = z.object({
|
|
|
87
93
|
solana_fee_sponsored: z.boolean().optional().catch(void 0),
|
|
88
94
|
solana_fee_policy_id: safeTextSchema(MAX_SECRET_LEN).optional().catch(void 0),
|
|
89
95
|
delegated_wallet: z.boolean().optional().catch(void 0),
|
|
90
|
-
active_signer: z.enum(["session", "local"]).optional().catch(void 0)
|
|
96
|
+
active_signer: z.enum(["session", "local"]).optional().catch(void 0),
|
|
97
|
+
wallet_client_instance_id: z.string().regex(UUID_RE).optional().catch(void 0),
|
|
98
|
+
wallet_client_instance_name: z.string().transform(normalizeWhitespace).pipe(safeTextSchema(MAX_WALLET_CLIENT_INSTANCE_NAME_LEN)).optional().catch(void 0)
|
|
91
99
|
}).strip();
|
|
100
|
+
function normalizeWhitespace(value) {
|
|
101
|
+
return value.trim().replace(/\s+/g, " ");
|
|
102
|
+
}
|
|
92
103
|
function sanitizeConfig(input) {
|
|
93
104
|
const parsed = configSchema.safeParse(input);
|
|
94
105
|
if (!parsed.success) {
|
|
@@ -134,6 +145,57 @@ function save(cfg) {
|
|
|
134
145
|
mode: 384
|
|
135
146
|
});
|
|
136
147
|
}
|
|
148
|
+
function normalizeWalletClientInstanceName(value) {
|
|
149
|
+
const normalized = normalizeWhitespace(value);
|
|
150
|
+
const parsed = safeTextSchema(MAX_WALLET_CLIENT_INSTANCE_NAME_LEN).safeParse(normalized);
|
|
151
|
+
return parsed.success ? parsed.data : void 0;
|
|
152
|
+
}
|
|
153
|
+
function deriveWalletClientInstanceIdFromName(name) {
|
|
154
|
+
const normalized = normalizeWalletClientInstanceName(name);
|
|
155
|
+
if (normalized === void 0) {
|
|
156
|
+
throw new Error("Invalid wallet client instance name.");
|
|
157
|
+
}
|
|
158
|
+
const digest = createHash("sha256").update(WALLET_CLIENT_INSTANCE_ID_NAMESPACE).update("\0").update(normalized.toLowerCase()).digest();
|
|
159
|
+
const bytes = Buffer.from(digest.subarray(0, 16));
|
|
160
|
+
bytes[6] = bytes[6] & 15 | 80;
|
|
161
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
162
|
+
const hex = bytes.toString("hex");
|
|
163
|
+
return [
|
|
164
|
+
hex.slice(0, 8),
|
|
165
|
+
hex.slice(8, 12),
|
|
166
|
+
hex.slice(12, 16),
|
|
167
|
+
hex.slice(16, 20),
|
|
168
|
+
hex.slice(20, 32)
|
|
169
|
+
].join("-");
|
|
170
|
+
}
|
|
171
|
+
function getOrCreateWalletClientInstance(input = {}) {
|
|
172
|
+
const cfg = load();
|
|
173
|
+
const instanceName = input.instanceName === void 0 ? cfg.wallet_client_instance_name : normalizeWalletClientInstanceName(input.instanceName);
|
|
174
|
+
if (input.instanceName !== void 0 && instanceName === void 0) {
|
|
175
|
+
throw new Error("Invalid wallet client instance name.");
|
|
176
|
+
}
|
|
177
|
+
if (instanceName !== void 0) {
|
|
178
|
+
const walletClientInstanceId2 = deriveWalletClientInstanceIdFromName(instanceName);
|
|
179
|
+
save({
|
|
180
|
+
...cfg,
|
|
181
|
+
wallet_client_instance_id: walletClientInstanceId2,
|
|
182
|
+
wallet_client_instance_name: instanceName
|
|
183
|
+
});
|
|
184
|
+
return {
|
|
185
|
+
id: walletClientInstanceId2,
|
|
186
|
+
name: instanceName
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
if (cfg.wallet_client_instance_id) {
|
|
190
|
+
return { id: cfg.wallet_client_instance_id };
|
|
191
|
+
}
|
|
192
|
+
const walletClientInstanceId = randomUUID();
|
|
193
|
+
save({
|
|
194
|
+
...cfg,
|
|
195
|
+
wallet_client_instance_id: walletClientInstanceId
|
|
196
|
+
});
|
|
197
|
+
return { id: walletClientInstanceId };
|
|
198
|
+
}
|
|
137
199
|
function get(cfg, key) {
|
|
138
200
|
if (key === "app") {
|
|
139
201
|
if (!cfg.app) return void 0;
|
|
@@ -192,6 +254,7 @@ export {
|
|
|
192
254
|
configDir,
|
|
193
255
|
load,
|
|
194
256
|
save,
|
|
257
|
+
getOrCreateWalletClientInstance,
|
|
195
258
|
get,
|
|
196
259
|
validKeys,
|
|
197
260
|
toMap
|
package/dist/chunk-HSKKIATB.js
CHANGED
|
File without changes
|
package/dist/chunk-HYCRHNPX.js
CHANGED
|
File without changes
|
package/dist/chunk-QEDAULQ2.js
CHANGED
|
File without changes
|
|
@@ -2,7 +2,7 @@
|
|
|
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-7WD3YLRK.js";
|
|
6
6
|
import {
|
|
7
7
|
esc
|
|
8
8
|
} from "./chunk-QEDAULQ2.js";
|
|
@@ -53,7 +53,7 @@ function semverLT(a, b) {
|
|
|
53
53
|
return false;
|
|
54
54
|
}
|
|
55
55
|
function currentVersion() {
|
|
56
|
-
return true ? "0.7.
|
|
56
|
+
return true ? "0.7.1" : "0.0.0";
|
|
57
57
|
}
|
|
58
58
|
function toUpdateStatus(latestVersion, checkedAt) {
|
|
59
59
|
const current = currentVersion();
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
import {
|
|
12
12
|
AdminClient,
|
|
13
13
|
resolveAuthToken
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-TOEVZMIP.js";
|
|
15
15
|
import {
|
|
16
16
|
bold,
|
|
17
17
|
brand,
|
|
@@ -20,13 +20,13 @@ import {
|
|
|
20
20
|
promptAutocomplete,
|
|
21
21
|
promptText,
|
|
22
22
|
withSpinner
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-5IFXLC2S.js";
|
|
24
24
|
import {
|
|
25
25
|
configPath,
|
|
26
26
|
load,
|
|
27
27
|
maskIf,
|
|
28
28
|
save
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-7WD3YLRK.js";
|
|
30
30
|
import {
|
|
31
31
|
CLIError,
|
|
32
32
|
ErrorCode,
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
configDir,
|
|
5
5
|
load,
|
|
6
6
|
save
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-7WD3YLRK.js";
|
|
8
8
|
import {
|
|
9
9
|
CLIError,
|
|
10
10
|
ErrorCode,
|
|
@@ -875,7 +875,9 @@ var walletSessionEnvironmentSchema = z.object({
|
|
|
875
875
|
platform: z.string().min(1),
|
|
876
876
|
arch: z.string().min(1),
|
|
877
877
|
nodeVersion: z.string().min(1),
|
|
878
|
-
interactive: z.boolean()
|
|
878
|
+
interactive: z.boolean(),
|
|
879
|
+
clientInstanceId: z.string().uuid().optional(),
|
|
880
|
+
clientInstanceName: z.string().min(1).max(64).optional()
|
|
879
881
|
}).strict();
|
|
880
882
|
var walletSessionSchema = z.object({
|
|
881
883
|
sessionId: z.string().uuid(),
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "./chunk-HYCRHNPX.js";
|
|
6
6
|
import {
|
|
7
7
|
resolveAuthToken
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-TOEVZMIP.js";
|
|
9
9
|
|
|
10
10
|
// src/lib/onboarding.ts
|
|
11
11
|
function hasAPIKey(cfg) {
|
|
@@ -43,7 +43,7 @@ function getSetupStatus(cfg) {
|
|
|
43
43
|
return {
|
|
44
44
|
complete: false,
|
|
45
45
|
satisfiedBy: null,
|
|
46
|
-
missing: ["Provide one auth path: alchemy auth OR api-key OR
|
|
46
|
+
missing: ["Provide one auth path: alchemy auth OR api-key OR ALCHEMY_ACCESS_KEY+app OR SIWx wallet"],
|
|
47
47
|
nextCommands: [
|
|
48
48
|
"alchemy auth",
|
|
49
49
|
"alchemy config set app",
|
package/dist/errors-3CNFGAXT.js
CHANGED
|
File without changes
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
|
|
3
3
|
import {
|
|
4
4
|
registerAuth
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-SYP6KKP6.js";
|
|
6
6
|
import {
|
|
7
7
|
openBrowser
|
|
8
8
|
} from "./chunk-HSKKIATB.js";
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
getSetupStatus,
|
|
11
11
|
isSetupComplete,
|
|
12
12
|
shouldRunOnboarding
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-V4IK4CJN.js";
|
|
14
14
|
import {
|
|
15
15
|
isInteractiveAllowed
|
|
16
16
|
} from "./chunk-HYCRHNPX.js";
|
|
@@ -41,12 +41,12 @@ import {
|
|
|
41
41
|
resolveX402Client,
|
|
42
42
|
saveSession,
|
|
43
43
|
updateSession
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-TOEVZMIP.js";
|
|
45
45
|
import {
|
|
46
46
|
getAvailableUpdate,
|
|
47
47
|
getUpdateStatus,
|
|
48
48
|
printUpdateNotice
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-RS3DSL3X.js";
|
|
50
50
|
import {
|
|
51
51
|
bold,
|
|
52
52
|
brand,
|
|
@@ -70,17 +70,18 @@ import {
|
|
|
70
70
|
weiToEth,
|
|
71
71
|
withSpinner,
|
|
72
72
|
yellow
|
|
73
|
-
} from "./chunk-
|
|
73
|
+
} from "./chunk-5IFXLC2S.js";
|
|
74
74
|
import {
|
|
75
75
|
KEY_MAP,
|
|
76
76
|
configDir,
|
|
77
77
|
get,
|
|
78
|
+
getOrCreateWalletClientInstance,
|
|
78
79
|
load,
|
|
79
80
|
maskIf,
|
|
80
81
|
save,
|
|
81
82
|
toMap,
|
|
82
83
|
validKeys
|
|
83
|
-
} from "./chunk-
|
|
84
|
+
} from "./chunk-7WD3YLRK.js";
|
|
84
85
|
import {
|
|
85
86
|
CLIError,
|
|
86
87
|
EXIT_CODES,
|
|
@@ -282,7 +283,6 @@ function validateTxHash(hash) {
|
|
|
282
283
|
|
|
283
284
|
// src/commands/config.ts
|
|
284
285
|
var RESET_KEY_MAP = { ...KEY_MAP, app: "app" };
|
|
285
|
-
var APP_SEARCH_THRESHOLD = 15;
|
|
286
286
|
async function saveAppWithPrompt(app) {
|
|
287
287
|
const cfg = load();
|
|
288
288
|
const updated = {
|
|
@@ -330,17 +330,12 @@ async function selectOrCreateApp(admin) {
|
|
|
330
330
|
})),
|
|
331
331
|
{ label: "Create a new app", value: CREATE_NEW }
|
|
332
332
|
];
|
|
333
|
-
const selected =
|
|
333
|
+
const selected = await promptAutocomplete({
|
|
334
334
|
message: "Select default app",
|
|
335
335
|
placeholder: "Type app name or id",
|
|
336
336
|
options,
|
|
337
337
|
cancelMessage: "Cancelled app selection.",
|
|
338
338
|
commitLabel: null
|
|
339
|
-
}) : await promptSelect({
|
|
340
|
-
message: "Select default app",
|
|
341
|
-
options,
|
|
342
|
-
cancelMessage: "Cancelled app selection.",
|
|
343
|
-
commitLabel: null
|
|
344
339
|
});
|
|
345
340
|
if (selected === null) {
|
|
346
341
|
return;
|
|
@@ -628,7 +623,7 @@ function registerConfig(program2) {
|
|
|
628
623
|
printJSON(toMap(cfg));
|
|
629
624
|
return;
|
|
630
625
|
}
|
|
631
|
-
const { resolveAuthToken: resolveAuthToken2 } = await import("./resolve-
|
|
626
|
+
const { resolveAuthToken: resolveAuthToken2 } = await import("./resolve-R4JZZCCF.js");
|
|
632
627
|
const validToken = resolveAuthToken2(cfg);
|
|
633
628
|
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");
|
|
634
629
|
const pairs = [
|
|
@@ -1184,8 +1179,9 @@ function registerApps(program2) {
|
|
|
1184
1179
|
printJSON({ apps: result.apps.map(maskAppSecrets) });
|
|
1185
1180
|
return;
|
|
1186
1181
|
}
|
|
1187
|
-
const appId = await
|
|
1182
|
+
const appId = await promptAutocomplete({
|
|
1188
1183
|
message: "Select an app",
|
|
1184
|
+
placeholder: "Type to search by name or id",
|
|
1189
1185
|
options: result.apps.map((app) => ({
|
|
1190
1186
|
value: app.id,
|
|
1191
1187
|
label: app.name,
|
|
@@ -1476,13 +1472,49 @@ function toProviderSigningBindingInput(input) {
|
|
|
1476
1472
|
};
|
|
1477
1473
|
}
|
|
1478
1474
|
async function createRemoteWalletSession(token, input) {
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1475
|
+
let data;
|
|
1476
|
+
let requestInput = input;
|
|
1477
|
+
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
1478
|
+
try {
|
|
1479
|
+
data = await request(
|
|
1480
|
+
token,
|
|
1481
|
+
"POST",
|
|
1482
|
+
"/wallet/sessions",
|
|
1483
|
+
requestInput
|
|
1484
|
+
);
|
|
1485
|
+
return unwrapAdminData(walletSessionCreateResponseSchema, data);
|
|
1486
|
+
} catch (err) {
|
|
1487
|
+
const retryInput = getClientInstanceCompatibilityRetryInput(requestInput, err);
|
|
1488
|
+
if (retryInput === void 0) {
|
|
1489
|
+
throw err;
|
|
1490
|
+
}
|
|
1491
|
+
requestInput = retryInput;
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
throw new CLIError(ErrorCode.NETWORK_ERROR, "Unable to create wallet session.");
|
|
1495
|
+
}
|
|
1496
|
+
function getClientInstanceCompatibilityRetryInput(input, err) {
|
|
1497
|
+
if (input.environment.clientInstanceName !== void 0 && isUnsupportedClientInstanceMetadataError(err, "clientInstanceName")) {
|
|
1498
|
+
const { clientInstanceName: _, ...environment } = input.environment;
|
|
1499
|
+
return {
|
|
1500
|
+
...input,
|
|
1501
|
+
environment
|
|
1502
|
+
};
|
|
1503
|
+
}
|
|
1504
|
+
if (input.environment.clientInstanceId !== void 0 && isUnsupportedClientInstanceMetadataError(err, "clientInstanceId")) {
|
|
1505
|
+
const { clientInstanceId: _, clientInstanceName: __, ...environment } = input.environment;
|
|
1506
|
+
return {
|
|
1507
|
+
...input,
|
|
1508
|
+
environment
|
|
1509
|
+
};
|
|
1510
|
+
}
|
|
1511
|
+
return void 0;
|
|
1512
|
+
}
|
|
1513
|
+
function isUnsupportedClientInstanceMetadataError(err, fieldName) {
|
|
1514
|
+
if (!(err instanceof CLIError)) {
|
|
1515
|
+
return false;
|
|
1516
|
+
}
|
|
1517
|
+
return err.code === ErrorCode.NETWORK_ERROR && err.message.includes("HTTP 400") && (err.details?.includes(fieldName) ?? true);
|
|
1486
1518
|
}
|
|
1487
1519
|
async function getRemoteWalletSession(token, sessionId) {
|
|
1488
1520
|
const data = await request(
|
|
@@ -2050,11 +2082,23 @@ async function runSessionConnect(opts) {
|
|
|
2050
2082
|
clearSession();
|
|
2051
2083
|
}
|
|
2052
2084
|
const session = createPendingSession();
|
|
2085
|
+
let clientInstance;
|
|
2086
|
+
try {
|
|
2087
|
+
clientInstance = getOrCreateWalletClientInstance({
|
|
2088
|
+
instanceName: opts.instanceName
|
|
2089
|
+
});
|
|
2090
|
+
} catch {
|
|
2091
|
+
throw errInvalidArgs(
|
|
2092
|
+
"`--instance-name` must be 1-64 characters and cannot contain control characters."
|
|
2093
|
+
);
|
|
2094
|
+
}
|
|
2053
2095
|
const sessionEnvironment = {
|
|
2054
2096
|
platform: process.platform,
|
|
2055
2097
|
arch: process.arch,
|
|
2056
2098
|
nodeVersion: process.version,
|
|
2057
|
-
interactive: isInteractiveAllowed(opts.program)
|
|
2099
|
+
interactive: isInteractiveAllowed(opts.program),
|
|
2100
|
+
clientInstanceId: clientInstance.id,
|
|
2101
|
+
...clientInstance.name === void 0 ? {} : { clientInstanceName: clientInstance.name }
|
|
2058
2102
|
};
|
|
2059
2103
|
updateSession({
|
|
2060
2104
|
chainType: "evm",
|
|
@@ -2077,13 +2121,17 @@ async function runSessionConnect(opts) {
|
|
|
2077
2121
|
expiresAt: remoteSession.expiresAt ?? session.expiresAt
|
|
2078
2122
|
});
|
|
2079
2123
|
if (!isJSONMode()) {
|
|
2080
|
-
|
|
2124
|
+
const summaryPairs = [
|
|
2081
2125
|
["Session ID", remoteSession.sessionId],
|
|
2082
2126
|
["Status", "pending"],
|
|
2083
2127
|
["Approval URL", remoteSession.approvalUrl],
|
|
2084
2128
|
["Created", session.createdAt],
|
|
2085
2129
|
["Expires", remoteSession.expiresAt ?? session.expiresAt]
|
|
2086
|
-
]
|
|
2130
|
+
];
|
|
2131
|
+
if (clientInstance.name !== void 0) {
|
|
2132
|
+
summaryPairs.splice(1, 0, ["Instance", clientInstance.name]);
|
|
2133
|
+
}
|
|
2134
|
+
printKeyValue(summaryPairs);
|
|
2087
2135
|
console.log(` ${green("\u2713")} Wallet session created`);
|
|
2088
2136
|
}
|
|
2089
2137
|
if (!isJSONMode() && isInteractiveAllowed(opts.program)) {
|
|
@@ -2236,6 +2284,12 @@ async function runConnectFlow(program2, opts) {
|
|
|
2236
2284
|
} else if (opts.mode !== void 0) {
|
|
2237
2285
|
throw errInvalidArgs("`--mode` must be 'session' or 'local'.");
|
|
2238
2286
|
}
|
|
2287
|
+
if (opts.instanceName !== void 0) {
|
|
2288
|
+
if (mode2 === "local") {
|
|
2289
|
+
throw errInvalidArgs("`--instance-name` is only valid with `--mode session`.");
|
|
2290
|
+
}
|
|
2291
|
+
mode2 = "session";
|
|
2292
|
+
}
|
|
2239
2293
|
if (importPath) {
|
|
2240
2294
|
if (mode2 === "session") {
|
|
2241
2295
|
throw errInvalidArgs("`--import` is only valid with `--mode local`.");
|
|
@@ -2272,7 +2326,7 @@ async function runConnectFlow(program2, opts) {
|
|
|
2272
2326
|
mode2 = choice;
|
|
2273
2327
|
}
|
|
2274
2328
|
if (mode2 === "session") {
|
|
2275
|
-
await runSessionConnect({ program: program2, force });
|
|
2329
|
+
await runSessionConnect({ program: program2, force, instanceName: opts.instanceName });
|
|
2276
2330
|
printCrossModeHintAfterSessionConnect();
|
|
2277
2331
|
return;
|
|
2278
2332
|
}
|
|
@@ -2333,7 +2387,7 @@ async function buildSessionSnapshot(program2, verify) {
|
|
|
2333
2387
|
}
|
|
2334
2388
|
function registerWallets(program2) {
|
|
2335
2389
|
const cmd = program2.command("wallet").description("Manage wallets");
|
|
2336
|
-
cmd.command("connect").description("Connect a wallet for onchain actions (session or local)").option("--mode <mode>", "session | local").option("--chain <chain>", "For --mode local: evm | solana | both (default: both)").option("--import <path>", "For --mode local: import EVM key from file (implies --chain evm)").option("--force", "Replace the existing signer").action(async (opts) => {
|
|
2390
|
+
cmd.command("connect").description("Connect a wallet for onchain actions (session or local)").option("--mode <mode>", "session | local").option("--chain <chain>", "For --mode local: evm | solana | both (default: both)").option("--import <path>", "For --mode local: import EVM key from file (implies --chain evm)").option("--instance-name <name>", "For --mode session: name this CLI instance").option("--force", "Replace the existing signer").action(async (opts) => {
|
|
2337
2391
|
try {
|
|
2338
2392
|
await runConnectFlow(program2, opts);
|
|
2339
2393
|
} catch (err) {
|
|
@@ -4584,7 +4638,7 @@ var ERROR_RECOVERY = {
|
|
|
4584
4638
|
NOT_FOUND: "Verify the resource identifier (address, hash, id) is correct",
|
|
4585
4639
|
RATE_LIMITED: "Wait and retry; consider upgrading your Alchemy plan",
|
|
4586
4640
|
PAYMENT_REQUIRED: "Fund your x402 wallet or switch to API key auth",
|
|
4587
|
-
SETUP_REQUIRED: "Run preflight: alchemy --json config status, then follow nextCommands",
|
|
4641
|
+
SETUP_REQUIRED: "Run preflight: alchemy --json --no-interactive config status, then follow nextCommands",
|
|
4588
4642
|
INTERNAL_ERROR: "Unexpected error; retry or report a bug"
|
|
4589
4643
|
};
|
|
4590
4644
|
function buildCommandSchema(cmd) {
|
|
@@ -4635,18 +4689,44 @@ function buildAgentPrompt(program2) {
|
|
|
4635
4689
|
"Parse stdout as JSON on exit code 0",
|
|
4636
4690
|
"Parse stderr as JSON on nonzero exit code",
|
|
4637
4691
|
"Never run bare 'alchemy' without --json --no-interactive",
|
|
4692
|
+
"Before answering Alchemy CLI capability or usage questions, inspect the live command contract from agent-prompt and trust it over model memory",
|
|
4693
|
+
"For general capability and usage questions, prefer npx -y @alchemy/cli@latest --json --no-interactive agent-prompt so stale local installs or PATH shims do not hide new commands",
|
|
4694
|
+
"Use the user's installed alchemy binary only when executing commands against their local config or diagnosing their installed version",
|
|
4695
|
+
"If installed alchemy help contradicts latest npm help, compare alchemy --json --no-interactive version with npx -y @alchemy/cli@latest --json --no-interactive version and check command -v alchemy",
|
|
4638
4696
|
"Run alchemy --json --no-interactive update-check when you need to detect available CLI upgrades"
|
|
4639
4697
|
],
|
|
4640
4698
|
preflight: {
|
|
4641
|
-
command: "alchemy --json config status",
|
|
4699
|
+
command: "alchemy --json --no-interactive config status",
|
|
4642
4700
|
description: "Check auth readiness before first command. If complete is false, follow nextCommands in the response to configure auth."
|
|
4643
4701
|
},
|
|
4702
|
+
runtimeDiscovery: {
|
|
4703
|
+
installed: {
|
|
4704
|
+
command: "alchemy --json --no-interactive agent-prompt",
|
|
4705
|
+
description: "Use for the user's currently installed CLI only when executing against local config or diagnosing local install behavior."
|
|
4706
|
+
},
|
|
4707
|
+
latest: {
|
|
4708
|
+
command: "npx -y @alchemy/cli@latest --json --no-interactive agent-prompt",
|
|
4709
|
+
description: "Default source of truth for general capability and usage questions; avoids stale local installs and PATH shims."
|
|
4710
|
+
},
|
|
4711
|
+
commandHelp: {
|
|
4712
|
+
commandTemplate: "npx -y @alchemy/cli@latest --no-interactive help <command...>",
|
|
4713
|
+
description: "Use for command-specific help from the latest published CLI when constructing an invocation."
|
|
4714
|
+
},
|
|
4715
|
+
versionCheck: {
|
|
4716
|
+
installedCommand: "alchemy --json --no-interactive version",
|
|
4717
|
+
latestCommand: "npx -y @alchemy/cli@latest --json --no-interactive version",
|
|
4718
|
+
description: "Compare when local help or agent-prompt output appears stale after an install or update."
|
|
4719
|
+
},
|
|
4720
|
+
pathCheck: {
|
|
4721
|
+
command: "command -v alchemy && alchemy version",
|
|
4722
|
+
description: "Use when installed CLI behavior contradicts the latest contract or an update appears not to take effect."
|
|
4723
|
+
}
|
|
4724
|
+
},
|
|
4644
4725
|
auth: [
|
|
4645
4726
|
{
|
|
4646
4727
|
method: "API key",
|
|
4647
4728
|
envVar: "ALCHEMY_API_KEY",
|
|
4648
4729
|
flag: "--api-key <key>",
|
|
4649
|
-
configKey: "api-key",
|
|
4650
4730
|
commandFamilies: [
|
|
4651
4731
|
"evm data",
|
|
4652
4732
|
"evm tx",
|
|
@@ -4666,9 +4746,9 @@ function buildAgentPrompt(program2) {
|
|
|
4666
4746
|
{
|
|
4667
4747
|
method: "Access key",
|
|
4668
4748
|
envVar: "ALCHEMY_ACCESS_KEY",
|
|
4669
|
-
flag: "--access-key <key>",
|
|
4670
4749
|
configKey: "access-key",
|
|
4671
|
-
commandFamilies: ["app", "evm network"]
|
|
4750
|
+
commandFamilies: ["app", "evm network"],
|
|
4751
|
+
notes: "No command-line flag exists for access-key auth; use the env var or saved config."
|
|
4672
4752
|
},
|
|
4673
4753
|
{
|
|
4674
4754
|
method: "Webhook API key",
|
|
@@ -4726,7 +4806,7 @@ function buildAgentPrompt(program2) {
|
|
|
4726
4806
|
"alchemy --json --no-interactive config status",
|
|
4727
4807
|
"alchemy --json --no-interactive update-check",
|
|
4728
4808
|
"alchemy --json --no-interactive evm data balance 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 --api-key $ALCHEMY_API_KEY",
|
|
4729
|
-
"alchemy --json --no-interactive app list
|
|
4809
|
+
"ALCHEMY_ACCESS_KEY=ak_xxx alchemy --json --no-interactive app list",
|
|
4730
4810
|
"alchemy --json --no-interactive evm rpc eth_blockNumber --api-key $ALCHEMY_API_KEY",
|
|
4731
4811
|
"alchemy --json --no-interactive evm network list",
|
|
4732
4812
|
"alchemy --json --no-interactive evm send 0xRecipient 0.001 -n eth-sepolia",
|
|
@@ -4751,11 +4831,26 @@ function formatAsSystemPrompt(payload) {
|
|
|
4751
4831
|
lines.push(` Command: ${payload.preflight.command}`);
|
|
4752
4832
|
lines.push(` ${payload.preflight.description}`);
|
|
4753
4833
|
lines.push("");
|
|
4834
|
+
lines.push("Runtime discovery:");
|
|
4835
|
+
lines.push(` Installed CLI: ${payload.runtimeDiscovery.installed.command}`);
|
|
4836
|
+
lines.push(` ${payload.runtimeDiscovery.installed.description}`);
|
|
4837
|
+
lines.push(` Latest npm CLI: ${payload.runtimeDiscovery.latest.command}`);
|
|
4838
|
+
lines.push(` ${payload.runtimeDiscovery.latest.description}`);
|
|
4839
|
+
lines.push(` Command help: ${payload.runtimeDiscovery.commandHelp.commandTemplate}`);
|
|
4840
|
+
lines.push(` ${payload.runtimeDiscovery.commandHelp.description}`);
|
|
4841
|
+
lines.push(` Installed version: ${payload.runtimeDiscovery.versionCheck.installedCommand}`);
|
|
4842
|
+
lines.push(` Latest npm version: ${payload.runtimeDiscovery.versionCheck.latestCommand}`);
|
|
4843
|
+
lines.push(` ${payload.runtimeDiscovery.versionCheck.description}`);
|
|
4844
|
+
lines.push(` Path check: ${payload.runtimeDiscovery.pathCheck.command}`);
|
|
4845
|
+
lines.push(` ${payload.runtimeDiscovery.pathCheck.description}`);
|
|
4846
|
+
lines.push("");
|
|
4754
4847
|
lines.push("Auth methods:");
|
|
4755
4848
|
for (const auth of payload.auth) {
|
|
4756
4849
|
lines.push(` ${auth.method}:`);
|
|
4757
4850
|
lines.push(` env: ${auth.envVar}`);
|
|
4758
|
-
|
|
4851
|
+
if (auth.flag) {
|
|
4852
|
+
lines.push(` flag: ${auth.flag}`);
|
|
4853
|
+
}
|
|
4759
4854
|
if (auth.configKey) {
|
|
4760
4855
|
lines.push(` config: alchemy config set ${auth.configKey} <value>`);
|
|
4761
4856
|
}
|
|
@@ -4783,7 +4878,7 @@ function formatAsSystemPrompt(payload) {
|
|
|
4783
4878
|
lines.push(" For RPC method signatures, parameters, and supported networks.");
|
|
4784
4879
|
lines.push("");
|
|
4785
4880
|
lines.push(
|
|
4786
|
-
"For full command tree, run: alchemy --json agent-prompt"
|
|
4881
|
+
"For full command tree, run: alchemy --json --no-interactive agent-prompt"
|
|
4787
4882
|
);
|
|
4788
4883
|
lines.push("");
|
|
4789
4884
|
return lines.join("\n");
|
|
@@ -7893,7 +7988,7 @@ function resetUpdateNoticeState() {
|
|
|
7893
7988
|
}
|
|
7894
7989
|
program.name("alchemy").description(
|
|
7895
7990
|
"The Alchemy CLI lets you query blockchain data, call JSON-RPC methods, and manage your Alchemy configuration."
|
|
7896
|
-
).version("0.7.
|
|
7991
|
+
).version("0.7.1", "-v, --version", "display CLI version").option("--api-key <key>", "Alchemy API key (env: ALCHEMY_API_KEY)").option(
|
|
7897
7992
|
"-n, --network <network>",
|
|
7898
7993
|
"Target network (default: eth-mainnet) (env: ALCHEMY_NETWORK)"
|
|
7899
7994
|
).option("--x402", "Use x402 wallet-based gateway auth").option(
|
|
@@ -8080,11 +8175,11 @@ ${styledLine}`;
|
|
|
8080
8175
|
"wallet"
|
|
8081
8176
|
];
|
|
8082
8177
|
if (!skipAppPrompt.includes(cmdName) && isInteractiveAllowed(program) && !opts.apiKey && !process.env.ALCHEMY_API_KEY) {
|
|
8083
|
-
const { resolveAuthToken: resolveAuthToken2 } = await import("./resolve-
|
|
8178
|
+
const { resolveAuthToken: resolveAuthToken2 } = await import("./resolve-R4JZZCCF.js");
|
|
8084
8179
|
const authToken = resolveAuthToken2(cfg);
|
|
8085
8180
|
const hasApiKey = Boolean(cfg.api_key?.trim() || cfg.app?.apiKey);
|
|
8086
8181
|
if (authToken && !hasApiKey) {
|
|
8087
|
-
const { selectAppAfterAuth } = await import("./auth-
|
|
8182
|
+
const { selectAppAfterAuth } = await import("./auth-BNT5Z5GZ.js");
|
|
8088
8183
|
console.log("");
|
|
8089
8184
|
console.log(` No app selected. Please select an app to continue.`);
|
|
8090
8185
|
await selectAppAfterAuth(authToken);
|
|
@@ -8115,7 +8210,7 @@ ${styledLine}`;
|
|
|
8115
8210
|
if (isInteractiveAllowed(program)) {
|
|
8116
8211
|
let latestForInteractiveStartup = null;
|
|
8117
8212
|
if (shouldRunOnboarding(program, cfg)) {
|
|
8118
|
-
const { runOnboarding } = await import("./onboarding-
|
|
8213
|
+
const { runOnboarding } = await import("./onboarding-S6HKWOEA.js");
|
|
8119
8214
|
const latest = getAvailableUpdateOnce();
|
|
8120
8215
|
const completed = await runOnboarding(program, latest);
|
|
8121
8216
|
updateShownDuringInteractiveStartup = Boolean(latest);
|
|
@@ -8129,7 +8224,7 @@ ${styledLine}`;
|
|
|
8129
8224
|
latestForInteractiveStartup
|
|
8130
8225
|
);
|
|
8131
8226
|
}
|
|
8132
|
-
const { startREPL } = await import("./interactive-
|
|
8227
|
+
const { startREPL } = await import("./interactive-N33RCX33.js");
|
|
8133
8228
|
program.exitOverride();
|
|
8134
8229
|
program.configureOutput({
|
|
8135
8230
|
writeErr: () => {
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
|
|
3
3
|
import {
|
|
4
4
|
getSetupMethod
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-V4IK4CJN.js";
|
|
6
6
|
import "./chunk-HYCRHNPX.js";
|
|
7
7
|
import {
|
|
8
8
|
getRPCNetworkIds
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-TOEVZMIP.js";
|
|
10
10
|
import {
|
|
11
11
|
getUpdateNoticeLines
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-RS3DSL3X.js";
|
|
13
13
|
import {
|
|
14
14
|
bold,
|
|
15
15
|
brand,
|
|
@@ -17,11 +17,11 @@ import {
|
|
|
17
17
|
dim,
|
|
18
18
|
green,
|
|
19
19
|
setBrandedHelpSuppressed
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-5IFXLC2S.js";
|
|
21
21
|
import {
|
|
22
22
|
configDir,
|
|
23
23
|
load
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-7WD3YLRK.js";
|
|
25
25
|
import {
|
|
26
26
|
bgRgb,
|
|
27
27
|
isJSONMode,
|
|
@@ -436,6 +436,9 @@ async function startREPL(program, latestUpdate = null) {
|
|
|
436
436
|
};
|
|
437
437
|
return new Promise((resolve) => {
|
|
438
438
|
rl.on("line", (line) => void onLine(line));
|
|
439
|
+
rl.on("SIGINT", () => {
|
|
440
|
+
rl.close();
|
|
441
|
+
});
|
|
439
442
|
rl.on("close", () => {
|
|
440
443
|
if (Array.isArray(rlWithHistory.history)) {
|
|
441
444
|
saveReplHistory([...rlWithHistory.history].reverse());
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
|
|
3
3
|
import {
|
|
4
4
|
getUpdateNoticeLines
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-RS3DSL3X.js";
|
|
6
6
|
import {
|
|
7
7
|
bold,
|
|
8
8
|
brand,
|
|
@@ -10,11 +10,11 @@ import {
|
|
|
10
10
|
dim,
|
|
11
11
|
green,
|
|
12
12
|
promptText
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-5IFXLC2S.js";
|
|
14
14
|
import {
|
|
15
15
|
load,
|
|
16
16
|
save
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-7WD3YLRK.js";
|
|
18
18
|
import "./chunk-QEDAULQ2.js";
|
|
19
19
|
|
|
20
20
|
// src/commands/onboarding.ts
|
|
@@ -51,7 +51,7 @@ async function runOnboarding(_program, latestUpdate = null) {
|
|
|
51
51
|
auth_token_expires_at: result.expiresAt
|
|
52
52
|
});
|
|
53
53
|
console.log(` ${green("\u2713")} Logged in successfully`);
|
|
54
|
-
const { selectAppAfterAuth } = await import("./auth-
|
|
54
|
+
const { selectAppAfterAuth } = await import("./auth-BNT5Z5GZ.js");
|
|
55
55
|
await selectAppAfterAuth(result.token);
|
|
56
56
|
return true;
|
|
57
57
|
} catch (err) {
|
|
@@ -22,8 +22,8 @@ import {
|
|
|
22
22
|
resolveWalletSession,
|
|
23
23
|
resolveX402,
|
|
24
24
|
resolveX402Client
|
|
25
|
-
} from "./chunk-
|
|
26
|
-
import "./chunk-
|
|
25
|
+
} from "./chunk-TOEVZMIP.js";
|
|
26
|
+
import "./chunk-7WD3YLRK.js";
|
|
27
27
|
import "./chunk-QEDAULQ2.js";
|
|
28
28
|
export {
|
|
29
29
|
adminClientFromFlags,
|
package/package.json
CHANGED
|
@@ -1,11 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alchemy/cli",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "Alchemy CLI — interact with blockchain data",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"alchemy": "./dist/index.js"
|
|
8
8
|
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsup",
|
|
11
|
+
"dev": "tsup --watch",
|
|
12
|
+
"live:check": "node --env-file-if-exists=.env.local --import=tsx scripts/live-check.ts",
|
|
13
|
+
"postinstall": "node ./scripts/postinstall.cjs",
|
|
14
|
+
"sync:skills": "node scripts/sync-skills.mjs",
|
|
15
|
+
"update:skills": "npx skills update && pnpm sync:skills",
|
|
16
|
+
"test": "vitest run",
|
|
17
|
+
"test:coverage": "vitest run --coverage",
|
|
18
|
+
"test:e2e": "pnpm build && vitest run --config vitest.e2e.config.ts",
|
|
19
|
+
"test:live": "pnpm build && node --env-file-if-exists=.env.local ./node_modules/vitest/vitest.mjs run --config vitest.live.config.ts",
|
|
20
|
+
"test:watch": "vitest",
|
|
21
|
+
"lint": "tsc --noEmit",
|
|
22
|
+
"changeset": "changeset",
|
|
23
|
+
"version-packages": "changeset version",
|
|
24
|
+
"release": "pnpm build && changeset publish"
|
|
25
|
+
},
|
|
9
26
|
"keywords": [
|
|
10
27
|
"alchemy",
|
|
11
28
|
"blockchain",
|
|
@@ -17,10 +34,6 @@
|
|
|
17
34
|
"README.md",
|
|
18
35
|
"scripts/postinstall.cjs"
|
|
19
36
|
],
|
|
20
|
-
"repository": {
|
|
21
|
-
"type": "git",
|
|
22
|
-
"url": "https://github.com/OMGWINNING/alchemy-cli.git"
|
|
23
|
-
},
|
|
24
37
|
"publishConfig": {
|
|
25
38
|
"access": "public"
|
|
26
39
|
},
|
|
@@ -29,7 +42,7 @@
|
|
|
29
42
|
"node": ">=22"
|
|
30
43
|
},
|
|
31
44
|
"dependencies": {
|
|
32
|
-
"@alchemy/wallet-apis": "5.0.0-beta.
|
|
45
|
+
"@alchemy/wallet-apis": "5.0.0-beta.28",
|
|
33
46
|
"@alchemy/x402": "^0.4.0",
|
|
34
47
|
"@noble/hashes": "^2.0.1",
|
|
35
48
|
"@solana-program/system": "^0.12.0",
|
|
@@ -51,21 +64,10 @@
|
|
|
51
64
|
"typescript": "^5.9.3",
|
|
52
65
|
"vitest": "^4.0.18"
|
|
53
66
|
},
|
|
54
|
-
"
|
|
55
|
-
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
"sync:skills": "node scripts/sync-skills.mjs",
|
|
60
|
-
"update:skills": "npx skills update && pnpm sync:skills",
|
|
61
|
-
"test": "vitest run",
|
|
62
|
-
"test:coverage": "vitest run --coverage",
|
|
63
|
-
"test:e2e": "pnpm build && vitest run --config vitest.e2e.config.ts",
|
|
64
|
-
"test:live": "pnpm build && node --env-file-if-exists=.env.local ./node_modules/vitest/vitest.mjs run --config vitest.live.config.ts",
|
|
65
|
-
"test:watch": "vitest",
|
|
66
|
-
"lint": "tsc --noEmit",
|
|
67
|
-
"changeset": "changeset",
|
|
68
|
-
"version-packages": "changeset version",
|
|
69
|
-
"release": "pnpm build && changeset publish"
|
|
67
|
+
"packageManager": "pnpm@10.18.2+sha512.9fb969fa749b3ade6035e0f109f0b8a60b5d08a1a87fdf72e337da90dcc93336e2280ca4e44f2358a649b83c17959e9993e777c2080879f3801e6f0d999ad3dd",
|
|
68
|
+
"pnpm": {
|
|
69
|
+
"overrides": {
|
|
70
|
+
"typebox": "1.0.81"
|
|
71
|
+
}
|
|
70
72
|
}
|
|
71
|
-
}
|
|
73
|
+
}
|