@grimoirelabs/cli 0.14.2 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/advisory-handlers.d.ts.map +1 -1
- package/dist/commands/advisory-handlers.js +1 -180
- package/dist/commands/advisory-handlers.js.map +1 -1
- package/dist/commands/advisory-live-trace.d.ts.map +1 -1
- package/dist/commands/advisory-live-trace.js +1 -1
- package/dist/commands/advisory-live-trace.js.map +1 -1
- package/dist/commands/advisory-verbose-trace.d.ts +15 -0
- package/dist/commands/advisory-verbose-trace.d.ts.map +1 -0
- package/dist/commands/advisory-verbose-trace.js +185 -0
- package/dist/commands/advisory-verbose-trace.js.map +1 -0
- package/dist/commands/cast-cross-chain.d.ts +69 -0
- package/dist/commands/cast-cross-chain.d.ts.map +1 -0
- package/dist/commands/cast-cross-chain.js +456 -0
- package/dist/commands/cast-cross-chain.js.map +1 -0
- package/dist/commands/cast.d.ts +1 -1
- package/dist/commands/cast.d.ts.map +1 -1
- package/dist/commands/cast.js +84 -709
- package/dist/commands/cast.js.map +1 -1
- package/dist/commands/compile-all.d.ts +15 -2
- package/dist/commands/compile-all.d.ts.map +1 -1
- package/dist/commands/compile-all.js +16 -21
- package/dist/commands/compile-all.js.map +1 -1
- package/dist/commands/compile.d.ts +1 -1
- package/dist/commands/compile.d.ts.map +1 -1
- package/dist/commands/compile.js +22 -26
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/cross-chain-helpers.d.ts +0 -1
- package/dist/commands/cross-chain-helpers.d.ts.map +1 -1
- package/dist/commands/cross-chain-helpers.js +0 -3
- package/dist/commands/cross-chain-helpers.js.map +1 -1
- package/dist/commands/history.d.ts +1 -2
- package/dist/commands/history.d.ts.map +1 -1
- package/dist/commands/history.js +59 -69
- package/dist/commands/history.js.map +1 -1
- package/dist/commands/init.d.ts +5 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +25 -20
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/log.d.ts +1 -2
- package/dist/commands/log.d.ts.map +1 -1
- package/dist/commands/log.js +9 -12
- package/dist/commands/log.js.map +1 -1
- package/dist/commands/resume.d.ts +18 -1
- package/dist/commands/resume.d.ts.map +1 -1
- package/dist/commands/resume.js +44 -66
- package/dist/commands/resume.js.map +1 -1
- package/dist/commands/setup-ui.d.ts +46 -0
- package/dist/commands/setup-ui.d.ts.map +1 -0
- package/dist/commands/setup-ui.js +221 -0
- package/dist/commands/setup-ui.js.map +1 -0
- package/dist/commands/setup.d.ts +31 -3
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +27 -270
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/simulate-cross-chain.d.ts +53 -0
- package/dist/commands/simulate-cross-chain.d.ts.map +1 -0
- package/dist/commands/simulate-cross-chain.js +256 -0
- package/dist/commands/simulate-cross-chain.js.map +1 -0
- package/dist/commands/simulate.d.ts +5 -1
- package/dist/commands/simulate.d.ts.map +1 -1
- package/dist/commands/simulate.js +16 -364
- package/dist/commands/simulate.js.map +1 -1
- package/dist/commands/state-helpers.d.ts.map +1 -1
- package/dist/commands/state-helpers.js +1 -5
- package/dist/commands/state-helpers.js.map +1 -1
- package/dist/commands/validate.d.ts +24 -2
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +40 -42
- package/dist/commands/validate.js.map +1 -1
- package/dist/commands/venue-doctor-morpho.d.ts +38 -0
- package/dist/commands/venue-doctor-morpho.d.ts.map +1 -0
- package/dist/commands/venue-doctor-morpho.js +214 -0
- package/dist/commands/venue-doctor-morpho.js.map +1 -0
- package/dist/commands/venue-doctor.d.ts +2 -26
- package/dist/commands/venue-doctor.d.ts.map +1 -1
- package/dist/commands/venue-doctor.js +17 -221
- package/dist/commands/venue-doctor.js.map +1 -1
- package/dist/commands/venue.d.ts.map +1 -1
- package/dist/commands/venue.js +11 -19
- package/dist/commands/venue.js.map +1 -1
- package/dist/commands/venues.d.ts +1 -5
- package/dist/commands/venues.d.ts.map +1 -1
- package/dist/commands/venues.js +5 -8
- package/dist/commands/venues.js.map +1 -1
- package/dist/commands/wallet-weth.d.ts +22 -0
- package/dist/commands/wallet-weth.d.ts.map +1 -0
- package/dist/commands/wallet-weth.js +150 -0
- package/dist/commands/wallet-weth.js.map +1 -0
- package/dist/commands/wallet.d.ts +65 -3
- package/dist/commands/wallet.d.ts.map +1 -1
- package/dist/commands/wallet.js +183 -377
- package/dist/commands/wallet.js.map +1 -1
- package/dist/index.js +375 -170
- package/dist/index.js.map +1 -1
- package/dist/lib/execution-helpers.d.ts +24 -0
- package/dist/lib/execution-helpers.d.ts.map +1 -0
- package/dist/lib/execution-helpers.js +133 -0
- package/dist/lib/execution-helpers.js.map +1 -0
- package/dist/lib/json.d.ts +8 -0
- package/dist/lib/json.d.ts.map +1 -0
- package/dist/lib/json.js +10 -0
- package/dist/lib/json.js.map +1 -0
- package/dist/lib/keystore.d.ts +12 -0
- package/dist/lib/keystore.d.ts.map +1 -0
- package/dist/lib/keystore.js +14 -0
- package/dist/lib/keystore.js.map +1 -0
- package/dist/lib/prompts.d.ts +16 -0
- package/dist/lib/prompts.d.ts.map +1 -0
- package/dist/lib/prompts.js +61 -0
- package/dist/lib/prompts.js.map +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Setup UI Helpers
|
|
3
|
+
* Interactive prompts, password resolution, and printing for setup command
|
|
4
|
+
*/
|
|
5
|
+
import { existsSync } from "node:fs";
|
|
6
|
+
import { chmod, writeFile } from "node:fs/promises";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
import chalk from "chalk";
|
|
9
|
+
import { DEFAULT_KEYSTORE_PATH } from "../lib/keystore.js";
|
|
10
|
+
import { promptLine, promptPassword } from "../lib/prompts.js";
|
|
11
|
+
export const DEFAULT_SETUP_ENV_FILE = join(".grimoire", "setup.env");
|
|
12
|
+
export const DEFAULT_PASSWORD_ENV = "KEYSTORE_PASSWORD";
|
|
13
|
+
export function resolveSetupRpcUrl(chainId, explicitRpcUrl, env) {
|
|
14
|
+
if (explicitRpcUrl && explicitRpcUrl.length > 0) {
|
|
15
|
+
return explicitRpcUrl;
|
|
16
|
+
}
|
|
17
|
+
return env[`RPC_URL_${chainId}`] ?? env.RPC_URL;
|
|
18
|
+
}
|
|
19
|
+
export function shouldRunVenueDoctor(options) {
|
|
20
|
+
if (options.noDoctor === true) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
if (options.doctor === false) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
export async function collectGuidedInputs(options, spinner) {
|
|
29
|
+
const guided = { ...options };
|
|
30
|
+
spinner.stop();
|
|
31
|
+
console.error();
|
|
32
|
+
console.error(chalk.cyan("Guided Setup (Execute Mode)"));
|
|
33
|
+
console.error(chalk.dim("Press Enter to accept defaults."));
|
|
34
|
+
console.error(chalk.dim("Sensitive password prompts are hidden and never echoed."));
|
|
35
|
+
if (guided.savePasswordEnv !== false) {
|
|
36
|
+
console.error(chalk.dim(`If you enter a password, setup will save ${DEFAULT_SETUP_ENV_FILE} for command reuse.`));
|
|
37
|
+
}
|
|
38
|
+
spinner.start();
|
|
39
|
+
if (!guided.chain) {
|
|
40
|
+
guided.chain = await promptValueWithSpinner(spinner, "Chain ID", "1");
|
|
41
|
+
}
|
|
42
|
+
const chainId = parsePositiveInteger(guided.chain, "--chain");
|
|
43
|
+
if (!guided.rpcUrl) {
|
|
44
|
+
const detected = resolveSetupRpcUrl(chainId, undefined, process.env);
|
|
45
|
+
const rpcInput = await promptValueWithSpinner(spinner, "RPC URL (blank to use default public RPC)", detected);
|
|
46
|
+
guided.rpcUrl = rpcInput.trim().length > 0 ? rpcInput.trim() : undefined;
|
|
47
|
+
}
|
|
48
|
+
if (guided.noDoctor === undefined && guided.doctor === undefined) {
|
|
49
|
+
const runDoctor = await promptYesNoWithSpinner(spinner, "Run venue doctor checks?", true);
|
|
50
|
+
guided.noDoctor = !runDoctor;
|
|
51
|
+
}
|
|
52
|
+
if (shouldRunVenueDoctor(guided) && (!guided.adapter || guided.adapter.trim().length === 0)) {
|
|
53
|
+
guided.adapter = await promptValueWithSpinner(spinner, "Adapter for venue doctor", "uniswap");
|
|
54
|
+
}
|
|
55
|
+
if (!guided.keystore || guided.keystore.trim().length === 0) {
|
|
56
|
+
guided.keystore = await promptValueWithSpinner(spinner, "Keystore path", DEFAULT_KEYSTORE_PATH);
|
|
57
|
+
}
|
|
58
|
+
const keystorePath = guided.keystore ?? DEFAULT_KEYSTORE_PATH;
|
|
59
|
+
const keyEnvDefault = guided.keyEnv ?? "PRIVATE_KEY";
|
|
60
|
+
const hasDefaultEnvKey = Boolean(process.env[keyEnvDefault]);
|
|
61
|
+
const keystoreExists = existsSync(keystorePath);
|
|
62
|
+
if (guided.importKey === true) {
|
|
63
|
+
guided.walletMode = "import_env_key";
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
guided.walletMode = await promptWalletModeWithSpinner(spinner, keystoreExists, hasDefaultEnvKey);
|
|
67
|
+
}
|
|
68
|
+
guided.importKey = guided.walletMode === "import_env_key";
|
|
69
|
+
if (guided.walletMode === "import_env_key") {
|
|
70
|
+
guided.keyEnv = await promptValueWithSpinner(spinner, "Private key env var", keyEnvDefault);
|
|
71
|
+
const importEnvName = guided.keyEnv ?? keyEnvDefault;
|
|
72
|
+
if (!process.env[importEnvName] || process.env[importEnvName]?.trim().length === 0) {
|
|
73
|
+
throw new Error(`Environment variable ${importEnvName} is not set. Export it first or choose wallet generation.`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (guided.walletMode !== "existing_keystore" && existsSync(keystorePath)) {
|
|
77
|
+
const overwrite = await promptYesNoWithSpinner(spinner, `Keystore exists at ${keystorePath}. Overwrite?`, false);
|
|
78
|
+
if (!overwrite) {
|
|
79
|
+
throw new Error("Setup canceled. Re-run with --keystore <new-path> or choose the existing keystore.");
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return guided;
|
|
83
|
+
}
|
|
84
|
+
export async function promptWalletModeWithSpinner(spinner, keystoreExists, hasDefaultEnvKey) {
|
|
85
|
+
if (keystoreExists) {
|
|
86
|
+
const useExisting = await promptYesNoWithSpinner(spinner, "Use existing keystore?", true);
|
|
87
|
+
if (useExisting) {
|
|
88
|
+
return "existing_keystore";
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const importDefault = hasDefaultEnvKey;
|
|
92
|
+
const importFromEnv = await promptYesNoWithSpinner(spinner, "Import wallet from a private key environment variable?", importDefault);
|
|
93
|
+
if (importFromEnv) {
|
|
94
|
+
return "import_env_key";
|
|
95
|
+
}
|
|
96
|
+
return "generate";
|
|
97
|
+
}
|
|
98
|
+
export function parsePositiveInteger(value, flag) {
|
|
99
|
+
const parsed = Number.parseInt(value ?? "1", 10);
|
|
100
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
101
|
+
throw new Error(`${flag} must be a positive integer`);
|
|
102
|
+
}
|
|
103
|
+
return parsed;
|
|
104
|
+
}
|
|
105
|
+
export function normalizePrivateKey(value) {
|
|
106
|
+
const trimmed = value.trim();
|
|
107
|
+
if (trimmed.length === 0) {
|
|
108
|
+
throw new Error("Private key value is empty.");
|
|
109
|
+
}
|
|
110
|
+
return (trimmed.startsWith("0x") ? trimmed : `0x${trimmed}`);
|
|
111
|
+
}
|
|
112
|
+
export async function resolveExistingKeystorePassword(options, interactive, spinner) {
|
|
113
|
+
const envName = options.passwordEnv ?? DEFAULT_PASSWORD_ENV;
|
|
114
|
+
const envValue = process.env[envName];
|
|
115
|
+
if (envValue) {
|
|
116
|
+
return { value: envValue, source: "env" };
|
|
117
|
+
}
|
|
118
|
+
if (!interactive) {
|
|
119
|
+
throw new Error(`No keystore password available. Set ${envName} or run interactively.`);
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
value: await promptPasswordWithSpinner(spinner, "Keystore password: "),
|
|
123
|
+
source: "prompt",
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
export async function resolveNewKeystorePassword(options, interactive, spinner) {
|
|
127
|
+
const envName = options.passwordEnv ?? DEFAULT_PASSWORD_ENV;
|
|
128
|
+
const envValue = process.env[envName];
|
|
129
|
+
if (envValue) {
|
|
130
|
+
return { value: envValue, source: "env" };
|
|
131
|
+
}
|
|
132
|
+
if (!interactive) {
|
|
133
|
+
throw new Error(`No keystore password available. Set ${envName} or run interactively.`);
|
|
134
|
+
}
|
|
135
|
+
const password = await promptPasswordWithSpinner(spinner, "New keystore password: ");
|
|
136
|
+
const confirm = await promptPasswordWithSpinner(spinner, "Confirm password: ");
|
|
137
|
+
if (password !== confirm) {
|
|
138
|
+
throw new Error("Passwords do not match.");
|
|
139
|
+
}
|
|
140
|
+
if (password.length === 0) {
|
|
141
|
+
throw new Error("Password must not be empty.");
|
|
142
|
+
}
|
|
143
|
+
return { value: password, source: "prompt" };
|
|
144
|
+
}
|
|
145
|
+
export async function promptPasswordWithSpinner(spinner, message) {
|
|
146
|
+
spinner.stop();
|
|
147
|
+
try {
|
|
148
|
+
return await promptPassword(message);
|
|
149
|
+
}
|
|
150
|
+
finally {
|
|
151
|
+
spinner.start();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
export async function promptValueWithSpinner(spinner, label, defaultValue) {
|
|
155
|
+
const prompt = defaultValue ? `${label} [${defaultValue}]: ` : `${label}: `;
|
|
156
|
+
const value = (await promptLineWithSpinner(spinner, prompt)).trim();
|
|
157
|
+
if (value.length > 0) {
|
|
158
|
+
return value;
|
|
159
|
+
}
|
|
160
|
+
return defaultValue ?? "";
|
|
161
|
+
}
|
|
162
|
+
export async function promptYesNoWithSpinner(spinner, label, defaultValue) {
|
|
163
|
+
const suffix = defaultValue ? "Y/n" : "y/N";
|
|
164
|
+
while (true) {
|
|
165
|
+
const answer = (await promptLineWithSpinner(spinner, `${label} [${suffix}]: `))
|
|
166
|
+
.trim()
|
|
167
|
+
.toLowerCase();
|
|
168
|
+
if (answer.length === 0) {
|
|
169
|
+
return defaultValue;
|
|
170
|
+
}
|
|
171
|
+
if (answer === "y" || answer === "yes") {
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
if (answer === "n" || answer === "no") {
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
spinner.stop();
|
|
178
|
+
console.error(chalk.yellow("Please answer yes or no."));
|
|
179
|
+
spinner.start();
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
export async function promptLineWithSpinner(spinner, message) {
|
|
183
|
+
spinner.stop();
|
|
184
|
+
try {
|
|
185
|
+
return await promptLine(message);
|
|
186
|
+
}
|
|
187
|
+
finally {
|
|
188
|
+
spinner.start();
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
export function printSetupStartWarning(passwordEnv) {
|
|
192
|
+
console.error(chalk.yellow("Security warning: never paste passwords or private keys into agent chat."));
|
|
193
|
+
console.error(chalk.dim(`Use hidden prompts, or preload secrets in your shell/secret manager and pass only --password-env ${passwordEnv}.`));
|
|
194
|
+
console.error();
|
|
195
|
+
}
|
|
196
|
+
export function printSetupPasswordGuidelines(passwordEnv, passwordEnvFile) {
|
|
197
|
+
console.error();
|
|
198
|
+
console.error(chalk.cyan("Password Safety"));
|
|
199
|
+
console.error(chalk.white(" 1. Do not type keystore passwords or private keys in Codex/Claude prompts."));
|
|
200
|
+
console.error(chalk.white(" 2. Prefer interactive hidden prompts: run commands without inline secret values."));
|
|
201
|
+
console.error(chalk.white(` 3. For non-interactive runs, preload ${passwordEnv} outside the agent and pass only the env var name.`));
|
|
202
|
+
if (passwordEnvFile) {
|
|
203
|
+
console.error(chalk.white(` 4. Grimoire auto-loads ${passwordEnvFile} on startup (existing env vars still take precedence).`));
|
|
204
|
+
console.error(chalk.white(" 5. The env file is plaintext. Keep it local and rotate/delete when not needed."));
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
console.error(chalk.white(" 4. Avoid inline secrets like KEYSTORE_PASSWORD=... grimoire ... because command logs may persist."));
|
|
208
|
+
}
|
|
209
|
+
export async function writeSetupPasswordEnvFile(envName, password) {
|
|
210
|
+
const escaped = password.replaceAll("'", "'\"'\"'");
|
|
211
|
+
const content = [
|
|
212
|
+
"# Generated by grimoire setup. Contains sensitive data.",
|
|
213
|
+
"# Keep this file local and do not commit it.",
|
|
214
|
+
`export ${envName}='${escaped}'`,
|
|
215
|
+
"",
|
|
216
|
+
].join("\n");
|
|
217
|
+
await writeFile(DEFAULT_SETUP_ENV_FILE, content, { encoding: "utf8", mode: 0o600 });
|
|
218
|
+
await chmod(DEFAULT_SETUP_ENV_FILE, 0o600);
|
|
219
|
+
return DEFAULT_SETUP_ENV_FILE;
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=setup-ui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-ui.js","sourceRoot":"","sources":["../../src/commands/setup-ui.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAE/D,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;AACrE,MAAM,CAAC,MAAM,oBAAoB,GAAG,mBAAmB,CAAC;AAoBxD,MAAM,UAAU,kBAAkB,CAChC,OAAe,EACf,cAAkC,EAClC,GAAuC;IAEvC,IAAI,cAAc,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChD,OAAO,cAAc,CAAC;IACxB,CAAC;IACD,OAAO,GAAG,CAAC,WAAW,OAAO,EAAE,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAAqB;IACxD,IAAI,OAAO,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,OAAqB,EACrB,OAA+B;IAE/B,MAAM,MAAM,GAAiB,EAAE,GAAG,OAAO,EAAE,CAAC;IAE5C,OAAO,CAAC,IAAI,EAAE,CAAC;IACf,OAAO,CAAC,KAAK,EAAE,CAAC;IAChB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,CAAC;IACzD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC,CAAC;IAC5D,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC,CAAC;IACpF,IAAI,MAAM,CAAC,eAAe,KAAK,KAAK,EAAE,CAAC;QACrC,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CACP,4CAA4C,sBAAsB,qBAAqB,CACxF,CACF,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,KAAK,EAAE,CAAC;IAEhB,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,CAAC,KAAK,GAAG,MAAM,sBAAsB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;IACxE,CAAC;IACD,MAAM,OAAO,GAAG,oBAAoB,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAE9D,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,QAAQ,GAAG,kBAAkB,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;QACrE,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAC3C,OAAO,EACP,2CAA2C,EAC3C,QAAQ,CACT,CAAC;QACF,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3E,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACjE,MAAM,SAAS,GAAG,MAAM,sBAAsB,CAAC,OAAO,EAAE,0BAA0B,EAAE,IAAI,CAAC,CAAC;QAC1F,MAAM,CAAC,QAAQ,GAAG,CAAC,SAAS,CAAC;IAC/B,CAAC;IAED,IAAI,oBAAoB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;QAC5F,MAAM,CAAC,OAAO,GAAG,MAAM,sBAAsB,CAAC,OAAO,EAAE,0BAA0B,EAAE,SAAS,CAAC,CAAC;IAChG,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5D,MAAM,CAAC,QAAQ,GAAG,MAAM,sBAAsB,CAAC,OAAO,EAAE,eAAe,EAAE,qBAAqB,CAAC,CAAC;IAClG,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,IAAI,qBAAqB,CAAC;IAC9D,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,IAAI,aAAa,CAAC;IACrD,MAAM,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;IAC7D,MAAM,cAAc,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IAEhD,IAAI,MAAM,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;QAC9B,MAAM,CAAC,UAAU,GAAG,gBAAgB,CAAC;IACvC,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,UAAU,GAAG,MAAM,2BAA2B,CACnD,OAAO,EACP,cAAc,EACd,gBAAgB,CACjB,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,UAAU,KAAK,gBAAgB,CAAC;IAC1D,IAAI,MAAM,CAAC,UAAU,KAAK,gBAAgB,EAAE,CAAC;QAC3C,MAAM,CAAC,MAAM,GAAG,MAAM,sBAAsB,CAAC,OAAO,EAAE,qBAAqB,EAAE,aAAa,CAAC,CAAC;QAC5F,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,IAAI,aAAa,CAAC;QACrD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnF,MAAM,IAAI,KAAK,CACb,wBAAwB,aAAa,2DAA2D,CACjG,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,UAAU,KAAK,mBAAmB,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC1E,MAAM,SAAS,GAAG,MAAM,sBAAsB,CAC5C,OAAO,EACP,sBAAsB,YAAY,cAAc,EAChD,KAAK,CACN,CAAC;QACF,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,oFAAoF,CACrF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,OAA+B,EAC/B,cAAuB,EACvB,gBAAyB;IAEzB,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,WAAW,GAAG,MAAM,sBAAsB,CAAC,OAAO,EAAE,wBAAwB,EAAE,IAAI,CAAC,CAAC;QAC1F,IAAI,WAAW,EAAE,CAAC;YAChB,OAAO,mBAAmB,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,MAAM,aAAa,GAAG,gBAAgB,CAAC;IACvC,MAAM,aAAa,GAAG,MAAM,sBAAsB,CAChD,OAAO,EACP,wDAAwD,EACxD,aAAa,CACd,CAAC;IACF,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAyB,EAAE,IAAY;IAC1E,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;IACjD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,6BAA6B,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,CAAkB,CAAC;AAChF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,+BAA+B,CACnD,OAAqB,EACrB,WAAoB,EACpB,OAA+B;IAE/B,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,IAAI,oBAAoB,CAAC;IAC5D,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACtC,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC5C,CAAC;IAED,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,uCAAuC,OAAO,wBAAwB,CAAC,CAAC;IAC1F,CAAC;IAED,OAAO;QACL,KAAK,EAAE,MAAM,yBAAyB,CAAC,OAAO,EAAE,qBAAqB,CAAC;QACtE,MAAM,EAAE,QAAQ;KACjB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,OAAqB,EACrB,WAAoB,EACpB,OAA+B;IAE/B,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,IAAI,oBAAoB,CAAC;IAC5D,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACtC,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC5C,CAAC;IAED,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,uCAAuC,OAAO,wBAAwB,CAAC,CAAC;IAC1F,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,yBAAyB,CAAC,OAAO,EAAE,yBAAyB,CAAC,CAAC;IACrF,MAAM,OAAO,GAAG,MAAM,yBAAyB,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC;IAC/E,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC/C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,OAA+B,EAC/B,OAAe;IAEf,OAAO,CAAC,IAAI,EAAE,CAAC;IACf,IAAI,CAAC;QACH,OAAO,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC;YAAS,CAAC;QACT,OAAO,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,OAA+B,EAC/B,KAAa,EACb,YAAqB;IAErB,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC;IAC5E,MAAM,KAAK,GAAG,CAAC,MAAM,qBAAqB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACpE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,YAAY,IAAI,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,OAA+B,EAC/B,KAAa,EACb,YAAqB;IAErB,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;IAC5C,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,MAAM,GAAG,CAAC,MAAM,qBAAqB,CAAC,OAAO,EAAE,GAAG,KAAK,KAAK,MAAM,KAAK,CAAC,CAAC;aAC5E,IAAI,EAAE;aACN,WAAW,EAAE,CAAC;QACjB,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,YAAY,CAAC;QACtB,CAAC;QACD,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACtC,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC,CAAC;QACxD,OAAO,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAA+B,EAC/B,OAAe;IAEf,OAAO,CAAC,IAAI,EAAE,CAAC;IACf,IAAI,CAAC;QACH,OAAO,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;YAAS,CAAC;QACT,OAAO,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,WAAmB;IACxD,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,MAAM,CAAC,0EAA0E,CAAC,CACzF,CAAC;IACF,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CACP,oGAAoG,WAAW,GAAG,CACnH,CACF,CAAC;IACF,OAAO,CAAC,KAAK,EAAE,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,WAAmB,EAAE,eAAwB;IACxF,OAAO,CAAC,KAAK,EAAE,CAAC;IAChB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,KAAK,CAAC,8EAA8E,CAAC,CAC5F,CAAC;IACF,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,KAAK,CACT,oFAAoF,CACrF,CACF,CAAC;IACF,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,KAAK,CACT,0CAA0C,WAAW,oDAAoD,CAC1G,CACF,CAAC;IACF,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,KAAK,CACT,4BAA4B,eAAe,wDAAwD,CACpG,CACF,CAAC;QACF,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,KAAK,CACT,kFAAkF,CACnF,CACF,CAAC;QACF,OAAO;IACT,CAAC;IACD,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,KAAK,CACT,qGAAqG,CACtG,CACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,OAAe,EACf,QAAgB;IAEhB,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG;QACd,yDAAyD;QACzD,8CAA8C;QAC9C,UAAU,OAAO,KAAK,OAAO,GAAG;QAChC,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,MAAM,SAAS,CAAC,sBAAsB,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACpF,MAAM,KAAK,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;IAC3C,OAAO,sBAAsB,CAAC;AAChC,CAAC"}
|
package/dist/commands/setup.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Setup Command
|
|
3
3
|
* Onboards local execute mode (wallet + RPC + readiness checks)
|
|
4
4
|
*/
|
|
5
|
+
export { resolveSetupRpcUrl } from "./setup-ui.js";
|
|
5
6
|
type WalletProvisionMode = "existing_keystore" | "import_env_key" | "generate";
|
|
6
7
|
interface SetupOptions {
|
|
7
8
|
chain?: string;
|
|
@@ -18,12 +19,39 @@ interface SetupOptions {
|
|
|
18
19
|
nonInteractive?: boolean;
|
|
19
20
|
json?: boolean;
|
|
20
21
|
}
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
interface SetupReport {
|
|
23
|
+
success: boolean;
|
|
24
|
+
mode: "execute";
|
|
25
|
+
chainId: number;
|
|
26
|
+
chainName: string;
|
|
27
|
+
rpcUrl: string;
|
|
28
|
+
rpcBlockNumber: string;
|
|
29
|
+
wallet: {
|
|
30
|
+
address: `0x${string}`;
|
|
31
|
+
keystore: string;
|
|
32
|
+
source: WalletProvisionMode;
|
|
33
|
+
balance: string;
|
|
34
|
+
balanceWei: string;
|
|
35
|
+
currency: string;
|
|
36
|
+
};
|
|
37
|
+
smoke: {
|
|
38
|
+
success: true;
|
|
39
|
+
spell: string;
|
|
40
|
+
};
|
|
41
|
+
passwordEnv: {
|
|
42
|
+
name: string;
|
|
43
|
+
file?: string;
|
|
44
|
+
};
|
|
45
|
+
venueDoctor?: {
|
|
46
|
+
adapter: string;
|
|
47
|
+
ok: boolean;
|
|
48
|
+
failedChecks: string[];
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export declare function setupCommand(options: SetupOptions): Promise<SetupReport>;
|
|
23
52
|
export declare function selectWalletProvisionMode(input: {
|
|
24
53
|
keystoreExists: boolean;
|
|
25
54
|
importKey: boolean;
|
|
26
55
|
keyEnvValue?: string;
|
|
27
56
|
}): WalletProvisionMode;
|
|
28
|
-
export {};
|
|
29
57
|
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAoCH,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAenD,KAAK,mBAAmB,GAAG,mBAAmB,GAAG,gBAAgB,GAAG,UAAU,CAAC;AAE/E,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,mBAAmB,CAAC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAWD,UAAU,WAAW;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE;QACN,OAAO,EAAE,KAAK,MAAM,EAAE,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,mBAAmB,CAAC;QAC5B,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,KAAK,EAAE;QACL,OAAO,EAAE,IAAI,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,WAAW,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,WAAW,CAAC,EAAE;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,EAAE,EAAE,OAAO,CAAC;QACZ,YAAY,EAAE,MAAM,EAAE,CAAC;KACxB,CAAC;CACH;AASD,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CA+K9E;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE;IAC/C,cAAc,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,mBAAmB,CAQtB"}
|
package/dist/commands/setup.js
CHANGED
|
@@ -3,19 +3,16 @@
|
|
|
3
3
|
* Onboards local execute mode (wallet + RPC + readiness checks)
|
|
4
4
|
*/
|
|
5
5
|
import { existsSync } from "node:fs";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { dirname, join } from "node:path";
|
|
9
|
-
import * as readline from "node:readline";
|
|
10
|
-
import { Writable } from "node:stream";
|
|
6
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
7
|
+
import { dirname } from "node:path";
|
|
11
8
|
import { compile, createKeystore, createProvider, createWalletFromConfig, formatWei, generatePrivateKey, getAddressFromConfig, getChainName, getNativeCurrencySymbol, preview, } from "@grimoirelabs/core";
|
|
12
9
|
import chalk from "chalk";
|
|
13
10
|
import ora from "ora";
|
|
11
|
+
import { DEFAULT_KEYSTORE_PATH } from "../lib/keystore.js";
|
|
12
|
+
import { collectGuidedInputs, DEFAULT_PASSWORD_ENV, normalizePrivateKey, parsePositiveInteger, printSetupPasswordGuidelines, printSetupStartWarning, resolveExistingKeystorePassword, resolveNewKeystorePassword, resolveSetupRpcUrl, shouldRunVenueDoctor, writeSetupPasswordEnvFile, } from "./setup-ui.js";
|
|
14
13
|
import { runVenueDoctor } from "./venue-doctor.js";
|
|
15
|
-
|
|
16
|
-
const DEFAULT_SETUP_ENV_FILE = join(".grimoire", "setup.env");
|
|
14
|
+
export { resolveSetupRpcUrl } from "./setup-ui.js";
|
|
17
15
|
const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
18
|
-
const DEFAULT_PASSWORD_ENV = "KEYSTORE_PASSWORD";
|
|
19
16
|
const SETUP_SMOKE_SPELL = `spell SetupSmoke {
|
|
20
17
|
params: {
|
|
21
18
|
amount: 21
|
|
@@ -124,35 +121,36 @@ export async function setupCommand(options) {
|
|
|
124
121
|
venueDoctor: venueDoctorSummary,
|
|
125
122
|
};
|
|
126
123
|
if (options.json) {
|
|
127
|
-
console.
|
|
128
|
-
return;
|
|
124
|
+
console.error(JSON.stringify(report, null, 2));
|
|
125
|
+
return report;
|
|
129
126
|
}
|
|
130
127
|
const adapter = effectiveOptions.adapter?.trim() || "uniswap";
|
|
131
|
-
console.
|
|
132
|
-
console.
|
|
133
|
-
console.
|
|
134
|
-
console.
|
|
135
|
-
console.
|
|
136
|
-
console.
|
|
137
|
-
console.
|
|
138
|
-
console.
|
|
139
|
-
console.
|
|
128
|
+
console.error();
|
|
129
|
+
console.error(chalk.cyan("Setup Summary"));
|
|
130
|
+
console.error(` ${chalk.dim("Mode:")} execute`);
|
|
131
|
+
console.error(` ${chalk.dim("Chain:")} ${chainName} (${chainId})`);
|
|
132
|
+
console.error(` ${chalk.dim("RPC:")} ${effectiveRpcUrl}`);
|
|
133
|
+
console.error(` ${chalk.dim("Block:")} ${blockNumber.toString()}`);
|
|
134
|
+
console.error(` ${chalk.dim("Wallet:")} ${wallet.address}`);
|
|
135
|
+
console.error(` ${chalk.dim("Keystore:")} ${walletSetup.keystorePath}`);
|
|
136
|
+
console.error(` ${chalk.dim("Password env:")} ${passwordEnv}`);
|
|
140
137
|
if (passwordEnvFile) {
|
|
141
|
-
console.
|
|
138
|
+
console.error(` ${chalk.dim("Password env file:")} ${passwordEnvFile}`);
|
|
142
139
|
}
|
|
143
|
-
console.
|
|
140
|
+
console.error(` ${chalk.dim("Balance:")} ${balance} ${currency}`);
|
|
144
141
|
if (balanceWei === 0n) {
|
|
145
|
-
console.
|
|
142
|
+
console.error(chalk.yellow(` Warning: wallet balance is zero ${currency}.`));
|
|
146
143
|
}
|
|
147
144
|
if (venueDoctorSummary) {
|
|
148
|
-
console.
|
|
145
|
+
console.error(` ${chalk.dim("Venue doctor:")} ${venueDoctorSummary.ok ? "pass" : "fail"} (${adapter})`);
|
|
149
146
|
}
|
|
150
147
|
const castCommand = `grimoire cast spells/uniswap-swap-execute.spell --dry-run --chain ${chainId} --rpc-url "${effectiveRpcUrl}" --keystore "${walletSetup.keystorePath}" --password-env ${passwordEnv}`;
|
|
151
|
-
console.
|
|
152
|
-
console.
|
|
153
|
-
console.
|
|
154
|
-
console.
|
|
148
|
+
console.error();
|
|
149
|
+
console.error(chalk.cyan("Next steps"));
|
|
150
|
+
console.error(chalk.white(` 1. ${castCommand}`));
|
|
151
|
+
console.error(chalk.white(` 2. grimoire venue doctor --adapter ${adapter} --chain ${chainId} --rpc-url "${effectiveRpcUrl}" --json`));
|
|
155
152
|
printSetupPasswordGuidelines(passwordEnv, passwordEnvFile);
|
|
153
|
+
return report;
|
|
156
154
|
}
|
|
157
155
|
catch (error) {
|
|
158
156
|
const message = error.message;
|
|
@@ -164,96 +162,11 @@ export async function setupCommand(options) {
|
|
|
164
162
|
stage,
|
|
165
163
|
error: message,
|
|
166
164
|
};
|
|
167
|
-
console.
|
|
165
|
+
console.error(JSON.stringify(payload, null, 2));
|
|
168
166
|
}
|
|
169
|
-
|
|
167
|
+
throw error;
|
|
170
168
|
}
|
|
171
169
|
}
|
|
172
|
-
function shouldRunVenueDoctor(options) {
|
|
173
|
-
if (options.noDoctor === true) {
|
|
174
|
-
return false;
|
|
175
|
-
}
|
|
176
|
-
if (options.doctor === false) {
|
|
177
|
-
return false;
|
|
178
|
-
}
|
|
179
|
-
return true;
|
|
180
|
-
}
|
|
181
|
-
async function collectGuidedInputs(options, spinner) {
|
|
182
|
-
const guided = { ...options };
|
|
183
|
-
spinner.stop();
|
|
184
|
-
console.log();
|
|
185
|
-
console.log(chalk.cyan("Guided Setup (Execute Mode)"));
|
|
186
|
-
console.log(chalk.dim("Press Enter to accept defaults."));
|
|
187
|
-
console.log(chalk.dim("Sensitive password prompts are hidden and never echoed."));
|
|
188
|
-
if (guided.savePasswordEnv !== false) {
|
|
189
|
-
console.log(chalk.dim(`If you enter a password, setup will save ${DEFAULT_SETUP_ENV_FILE} for command reuse.`));
|
|
190
|
-
}
|
|
191
|
-
spinner.start();
|
|
192
|
-
if (!guided.chain) {
|
|
193
|
-
guided.chain = await promptValueWithSpinner(spinner, "Chain ID", "1");
|
|
194
|
-
}
|
|
195
|
-
const chainId = parsePositiveInteger(guided.chain, "--chain");
|
|
196
|
-
if (!guided.rpcUrl) {
|
|
197
|
-
const detected = resolveSetupRpcUrl(chainId, undefined, process.env);
|
|
198
|
-
const rpcInput = await promptValueWithSpinner(spinner, "RPC URL (blank to use default public RPC)", detected);
|
|
199
|
-
guided.rpcUrl = rpcInput.trim().length > 0 ? rpcInput.trim() : undefined;
|
|
200
|
-
}
|
|
201
|
-
if (guided.noDoctor === undefined && guided.doctor === undefined) {
|
|
202
|
-
const runDoctor = await promptYesNoWithSpinner(spinner, "Run venue doctor checks?", true);
|
|
203
|
-
guided.noDoctor = !runDoctor;
|
|
204
|
-
}
|
|
205
|
-
if (shouldRunVenueDoctor(guided) && (!guided.adapter || guided.adapter.trim().length === 0)) {
|
|
206
|
-
guided.adapter = await promptValueWithSpinner(spinner, "Adapter for venue doctor", "uniswap");
|
|
207
|
-
}
|
|
208
|
-
if (!guided.keystore || guided.keystore.trim().length === 0) {
|
|
209
|
-
guided.keystore = await promptValueWithSpinner(spinner, "Keystore path", DEFAULT_KEYSTORE_PATH);
|
|
210
|
-
}
|
|
211
|
-
const keystorePath = guided.keystore ?? DEFAULT_KEYSTORE_PATH;
|
|
212
|
-
const keyEnvDefault = guided.keyEnv ?? "PRIVATE_KEY";
|
|
213
|
-
const hasDefaultEnvKey = Boolean(process.env[keyEnvDefault]);
|
|
214
|
-
const keystoreExists = existsSync(keystorePath);
|
|
215
|
-
if (guided.importKey === true) {
|
|
216
|
-
guided.walletMode = "import_env_key";
|
|
217
|
-
}
|
|
218
|
-
else {
|
|
219
|
-
guided.walletMode = await promptWalletModeWithSpinner(spinner, keystoreExists, hasDefaultEnvKey);
|
|
220
|
-
}
|
|
221
|
-
guided.importKey = guided.walletMode === "import_env_key";
|
|
222
|
-
if (guided.walletMode === "import_env_key") {
|
|
223
|
-
guided.keyEnv = await promptValueWithSpinner(spinner, "Private key env var", keyEnvDefault);
|
|
224
|
-
const importEnvName = guided.keyEnv ?? keyEnvDefault;
|
|
225
|
-
if (!process.env[importEnvName] || process.env[importEnvName]?.trim().length === 0) {
|
|
226
|
-
throw new Error(`Environment variable ${importEnvName} is not set. Export it first or choose wallet generation.`);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
if (guided.walletMode !== "existing_keystore" && existsSync(keystorePath)) {
|
|
230
|
-
const overwrite = await promptYesNoWithSpinner(spinner, `Keystore exists at ${keystorePath}. Overwrite?`, false);
|
|
231
|
-
if (!overwrite) {
|
|
232
|
-
throw new Error("Setup canceled. Re-run with --keystore <new-path> or choose the existing keystore.");
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
return guided;
|
|
236
|
-
}
|
|
237
|
-
async function promptWalletModeWithSpinner(spinner, keystoreExists, hasDefaultEnvKey) {
|
|
238
|
-
if (keystoreExists) {
|
|
239
|
-
const useExisting = await promptYesNoWithSpinner(spinner, "Use existing keystore?", true);
|
|
240
|
-
if (useExisting) {
|
|
241
|
-
return "existing_keystore";
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
const importDefault = hasDefaultEnvKey;
|
|
245
|
-
const importFromEnv = await promptYesNoWithSpinner(spinner, "Import wallet from a private key environment variable?", importDefault);
|
|
246
|
-
if (importFromEnv) {
|
|
247
|
-
return "import_env_key";
|
|
248
|
-
}
|
|
249
|
-
return "generate";
|
|
250
|
-
}
|
|
251
|
-
export function resolveSetupRpcUrl(chainId, explicitRpcUrl, env) {
|
|
252
|
-
if (explicitRpcUrl && explicitRpcUrl.length > 0) {
|
|
253
|
-
return explicitRpcUrl;
|
|
254
|
-
}
|
|
255
|
-
return env[`RPC_URL_${chainId}`] ?? env.RPC_URL;
|
|
256
|
-
}
|
|
257
170
|
export function selectWalletProvisionMode(input) {
|
|
258
171
|
if (input.keystoreExists) {
|
|
259
172
|
return "existing_keystore";
|
|
@@ -348,160 +261,4 @@ async function setupWallet(options, spinner, interactive) {
|
|
|
348
261
|
passwordSource: password.source,
|
|
349
262
|
};
|
|
350
263
|
}
|
|
351
|
-
function parsePositiveInteger(value, flag) {
|
|
352
|
-
const parsed = Number.parseInt(value ?? "1", 10);
|
|
353
|
-
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
354
|
-
throw new Error(`${flag} must be a positive integer`);
|
|
355
|
-
}
|
|
356
|
-
return parsed;
|
|
357
|
-
}
|
|
358
|
-
function normalizePrivateKey(value) {
|
|
359
|
-
const trimmed = value.trim();
|
|
360
|
-
if (trimmed.length === 0) {
|
|
361
|
-
throw new Error("Private key value is empty.");
|
|
362
|
-
}
|
|
363
|
-
return (trimmed.startsWith("0x") ? trimmed : `0x${trimmed}`);
|
|
364
|
-
}
|
|
365
|
-
async function resolveExistingKeystorePassword(options, interactive, spinner) {
|
|
366
|
-
const envName = options.passwordEnv ?? DEFAULT_PASSWORD_ENV;
|
|
367
|
-
const envValue = process.env[envName];
|
|
368
|
-
if (envValue) {
|
|
369
|
-
return { value: envValue, source: "env" };
|
|
370
|
-
}
|
|
371
|
-
if (!interactive) {
|
|
372
|
-
throw new Error(`No keystore password available. Set ${envName} or run interactively.`);
|
|
373
|
-
}
|
|
374
|
-
return {
|
|
375
|
-
value: await promptPasswordWithSpinner(spinner, "Keystore password: "),
|
|
376
|
-
source: "prompt",
|
|
377
|
-
};
|
|
378
|
-
}
|
|
379
|
-
async function resolveNewKeystorePassword(options, interactive, spinner) {
|
|
380
|
-
const envName = options.passwordEnv ?? DEFAULT_PASSWORD_ENV;
|
|
381
|
-
const envValue = process.env[envName];
|
|
382
|
-
if (envValue) {
|
|
383
|
-
return { value: envValue, source: "env" };
|
|
384
|
-
}
|
|
385
|
-
if (!interactive) {
|
|
386
|
-
throw new Error(`No keystore password available. Set ${envName} or run interactively.`);
|
|
387
|
-
}
|
|
388
|
-
const password = await promptPasswordWithSpinner(spinner, "New keystore password: ");
|
|
389
|
-
const confirm = await promptPasswordWithSpinner(spinner, "Confirm password: ");
|
|
390
|
-
if (password !== confirm) {
|
|
391
|
-
throw new Error("Passwords do not match.");
|
|
392
|
-
}
|
|
393
|
-
if (password.length === 0) {
|
|
394
|
-
throw new Error("Password must not be empty.");
|
|
395
|
-
}
|
|
396
|
-
return { value: password, source: "prompt" };
|
|
397
|
-
}
|
|
398
|
-
async function promptPasswordWithSpinner(spinner, message) {
|
|
399
|
-
spinner.stop();
|
|
400
|
-
try {
|
|
401
|
-
return await promptPassword(message);
|
|
402
|
-
}
|
|
403
|
-
finally {
|
|
404
|
-
spinner.start();
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
async function promptValueWithSpinner(spinner, label, defaultValue) {
|
|
408
|
-
const prompt = defaultValue ? `${label} [${defaultValue}]: ` : `${label}: `;
|
|
409
|
-
const value = (await promptLineWithSpinner(spinner, prompt)).trim();
|
|
410
|
-
if (value.length > 0) {
|
|
411
|
-
return value;
|
|
412
|
-
}
|
|
413
|
-
return defaultValue ?? "";
|
|
414
|
-
}
|
|
415
|
-
async function promptYesNoWithSpinner(spinner, label, defaultValue) {
|
|
416
|
-
const suffix = defaultValue ? "Y/n" : "y/N";
|
|
417
|
-
while (true) {
|
|
418
|
-
const answer = (await promptLineWithSpinner(spinner, `${label} [${suffix}]: `))
|
|
419
|
-
.trim()
|
|
420
|
-
.toLowerCase();
|
|
421
|
-
if (answer.length === 0) {
|
|
422
|
-
return defaultValue;
|
|
423
|
-
}
|
|
424
|
-
if (answer === "y" || answer === "yes") {
|
|
425
|
-
return true;
|
|
426
|
-
}
|
|
427
|
-
if (answer === "n" || answer === "no") {
|
|
428
|
-
return false;
|
|
429
|
-
}
|
|
430
|
-
spinner.stop();
|
|
431
|
-
console.log(chalk.yellow("Please answer yes or no."));
|
|
432
|
-
spinner.start();
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
async function promptLineWithSpinner(spinner, message) {
|
|
436
|
-
spinner.stop();
|
|
437
|
-
try {
|
|
438
|
-
return await promptLine(message);
|
|
439
|
-
}
|
|
440
|
-
finally {
|
|
441
|
-
spinner.start();
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
async function promptLine(message) {
|
|
445
|
-
return await new Promise((resolve) => {
|
|
446
|
-
const rl = readline.createInterface({
|
|
447
|
-
input: process.stdin,
|
|
448
|
-
output: process.stdout,
|
|
449
|
-
terminal: true,
|
|
450
|
-
});
|
|
451
|
-
rl.question(message, (answer) => {
|
|
452
|
-
rl.close();
|
|
453
|
-
resolve(answer);
|
|
454
|
-
});
|
|
455
|
-
});
|
|
456
|
-
}
|
|
457
|
-
async function promptPassword(message) {
|
|
458
|
-
return await new Promise((resolve) => {
|
|
459
|
-
process.stdout.write(message);
|
|
460
|
-
const silentOutput = new Writable({
|
|
461
|
-
write(_chunk, _encoding, callback) {
|
|
462
|
-
callback();
|
|
463
|
-
},
|
|
464
|
-
});
|
|
465
|
-
const rl = readline.createInterface({
|
|
466
|
-
input: process.stdin,
|
|
467
|
-
output: silentOutput,
|
|
468
|
-
terminal: true,
|
|
469
|
-
});
|
|
470
|
-
rl.question("", (answer) => {
|
|
471
|
-
rl.close();
|
|
472
|
-
process.stdout.write("\n");
|
|
473
|
-
resolve(answer);
|
|
474
|
-
});
|
|
475
|
-
});
|
|
476
|
-
}
|
|
477
|
-
function printSetupStartWarning(passwordEnv) {
|
|
478
|
-
console.log(chalk.yellow("Security warning: never paste passwords or private keys into agent chat."));
|
|
479
|
-
console.log(chalk.dim(`Use hidden prompts, or preload secrets in your shell/secret manager and pass only --password-env ${passwordEnv}.`));
|
|
480
|
-
console.log();
|
|
481
|
-
}
|
|
482
|
-
function printSetupPasswordGuidelines(passwordEnv, passwordEnvFile) {
|
|
483
|
-
console.log();
|
|
484
|
-
console.log(chalk.cyan("Password Safety"));
|
|
485
|
-
console.log(chalk.white(" 1. Do not type keystore passwords or private keys in Codex/Claude prompts."));
|
|
486
|
-
console.log(chalk.white(" 2. Prefer interactive hidden prompts: run commands without inline secret values."));
|
|
487
|
-
console.log(chalk.white(` 3. For non-interactive runs, preload ${passwordEnv} outside the agent and pass only the env var name.`));
|
|
488
|
-
if (passwordEnvFile) {
|
|
489
|
-
console.log(chalk.white(` 4. Grimoire auto-loads ${passwordEnvFile} on startup (existing env vars still take precedence).`));
|
|
490
|
-
console.log(chalk.white(" 5. The env file is plaintext. Keep it local and rotate/delete when not needed."));
|
|
491
|
-
return;
|
|
492
|
-
}
|
|
493
|
-
console.log(chalk.white(" 4. Avoid inline secrets like KEYSTORE_PASSWORD=... grimoire ... because command logs may persist."));
|
|
494
|
-
}
|
|
495
|
-
async function writeSetupPasswordEnvFile(envName, password) {
|
|
496
|
-
const escaped = password.replaceAll("'", "'\"'\"'");
|
|
497
|
-
const content = [
|
|
498
|
-
"# Generated by grimoire setup. Contains sensitive data.",
|
|
499
|
-
"# Keep this file local and do not commit it.",
|
|
500
|
-
`export ${envName}='${escaped}'`,
|
|
501
|
-
"",
|
|
502
|
-
].join("\n");
|
|
503
|
-
await writeFile(DEFAULT_SETUP_ENV_FILE, content, { encoding: "utf8", mode: 0o600 });
|
|
504
|
-
await chmod(DEFAULT_SETUP_ENV_FILE, 0o600);
|
|
505
|
-
return DEFAULT_SETUP_ENV_FILE;
|
|
506
|
-
}
|
|
507
264
|
//# sourceMappingURL=setup.js.map
|