@vault77/summon 2.1.3 → 2.1.7
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 +1 -1
- package/package.json +9 -9
- package/summon-cli.js +92 -15
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|

|
|
5
5
|

|
|
6
6
|
|
|
7
|
-
**Version:** 2.1.
|
|
7
|
+
**Version:** 2.1.7
|
|
8
8
|
|
|
9
9
|
> _Relic software unearthed from VAULT77.
|
|
10
10
|
> For trench operators only. macOS‑native. Handle with care._
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vault77/summon",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.7",
|
|
4
4
|
"description": "A recovered VAULT77 relic for macOS operators. summonTheWarlord is a high-performance CLI tool for ultra-fast, low-fee Solana swaps on macOS. Private keys are secured using the native macOS Keychain, never written to disk or exposed to JavaScript memory longer than required. Built for serious CLI workflows with system notifications, local-first execution, and zero browser dependency.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"solana",
|
|
@@ -16,17 +16,17 @@
|
|
|
16
16
|
"author": "Humble Digital, llc <SummonTheWarlord@pm.me>",
|
|
17
17
|
"repository": {
|
|
18
18
|
"type": "git",
|
|
19
|
-
"url": "git+https://github.com/
|
|
19
|
+
"url": "git+https://github.com/HumbleDigital/summonTheWarlord.git"
|
|
20
20
|
},
|
|
21
|
-
"homepage": "https://github.com/
|
|
21
|
+
"homepage": "https://github.com/HumbleDigital/summonTheWarlord#readme",
|
|
22
22
|
"bugs": {
|
|
23
|
-
"url": "https://github.com/
|
|
23
|
+
"url": "https://github.com/HumbleDigital/summonTheWarlord/issues"
|
|
24
24
|
},
|
|
25
25
|
"type": "module",
|
|
26
26
|
"license": "MIT",
|
|
27
27
|
"main": "summon-cli.js",
|
|
28
28
|
"bin": {
|
|
29
|
-
"summon": "
|
|
29
|
+
"summon": "summon-cli.js"
|
|
30
30
|
},
|
|
31
31
|
"publishConfig": {
|
|
32
32
|
"access": "public"
|
|
@@ -47,15 +47,15 @@
|
|
|
47
47
|
"lint:fix": "eslint . --fix"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@eslint/js": "^9.39.
|
|
51
|
-
"eslint": "^9.39.
|
|
50
|
+
"@eslint/js": "^9.39.4",
|
|
51
|
+
"eslint": "^9.39.3",
|
|
52
52
|
"eslint-plugin-import": "^2.32.0",
|
|
53
|
-
"globals": "^17.
|
|
53
|
+
"globals": "^17.4.0",
|
|
54
54
|
"jest": "^30.2.0"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"@solana/web3.js": "^1.98.4",
|
|
58
|
-
"axios": "^1.13.
|
|
58
|
+
"axios": "^1.13.6",
|
|
59
59
|
"bs58": "^6.0.0",
|
|
60
60
|
"commander": "^14.0.3",
|
|
61
61
|
"fs-extra": "^11.3.3",
|
package/summon-cli.js
CHANGED
|
@@ -102,6 +102,30 @@ const WIZARD_FIELD_GUIDANCE = {
|
|
|
102
102
|
const askQuestion = (rl, prompt) =>
|
|
103
103
|
new Promise((resolve) => rl.question(prompt, (answer) => resolve(answer.trim())));
|
|
104
104
|
|
|
105
|
+
async function askSecretQuestion(rl, prompt) {
|
|
106
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
107
|
+
return askQuestion(rl, prompt);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const originalWrite = rl._writeToOutput?.bind(rl);
|
|
111
|
+
rl.output.write(prompt);
|
|
112
|
+
rl._writeToOutput = () => {};
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
const answer = await new Promise((resolve) => rl.question("", resolve));
|
|
116
|
+
rl.output.write("\n");
|
|
117
|
+
return String(answer).trim();
|
|
118
|
+
} finally {
|
|
119
|
+
if (originalWrite) {
|
|
120
|
+
rl._writeToOutput = originalWrite;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function printKeychainAccessHint() {
|
|
126
|
+
console.log(' Check it in Keychain Access by searching for "summonTheWarlord" and opening "wallet-private-key".');
|
|
127
|
+
}
|
|
128
|
+
|
|
105
129
|
const COLOR_ENABLED = process.stdout.isTTY;
|
|
106
130
|
const ANSI = {
|
|
107
131
|
reset: "\x1b[0m",
|
|
@@ -113,6 +137,53 @@ const ANSI = {
|
|
|
113
137
|
};
|
|
114
138
|
|
|
115
139
|
const paint = (text, color) => (COLOR_ENABLED ? `${color}${text}${ANSI.reset}` : text);
|
|
140
|
+
const SENSITIVE_URL_KEY_PATTERN = /key|token|secret|auth|signature|sig|password|pwd/i;
|
|
141
|
+
|
|
142
|
+
function maskSensitiveValue(value) {
|
|
143
|
+
const text = String(value ?? "");
|
|
144
|
+
if (!text) {
|
|
145
|
+
return text;
|
|
146
|
+
}
|
|
147
|
+
if (text.length <= 4) {
|
|
148
|
+
return "*".repeat(text.length);
|
|
149
|
+
}
|
|
150
|
+
return `${"*".repeat(text.length - 4)}${text.slice(-4)}`;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function redactSensitiveUrl(rawUrl) {
|
|
154
|
+
const urlText = String(rawUrl ?? "").trim();
|
|
155
|
+
if (!urlText) {
|
|
156
|
+
return urlText;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
try {
|
|
160
|
+
const parsed = new URL(urlText);
|
|
161
|
+
if (parsed.username) {
|
|
162
|
+
parsed.username = maskSensitiveValue(parsed.username);
|
|
163
|
+
}
|
|
164
|
+
if (parsed.password) {
|
|
165
|
+
parsed.password = maskSensitiveValue(parsed.password);
|
|
166
|
+
}
|
|
167
|
+
for (const [key, value] of parsed.searchParams.entries()) {
|
|
168
|
+
if (SENSITIVE_URL_KEY_PATTERN.test(key)) {
|
|
169
|
+
parsed.searchParams.set(key, maskSensitiveValue(value));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return parsed.toString();
|
|
173
|
+
} catch {
|
|
174
|
+
return urlText.replace(
|
|
175
|
+
/([?&][^=]*(?:key|token|secret|auth|signature|sig|password|pwd)[^=]*=)([^&]+)/ig,
|
|
176
|
+
(_, prefix, value) => `${prefix}${maskSensitiveValue(value)}`
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function formatConfigDisplayValue(key, value) {
|
|
182
|
+
if (key === "rpcUrl") {
|
|
183
|
+
return redactSensitiveUrl(value);
|
|
184
|
+
}
|
|
185
|
+
return toDisplayValue(value);
|
|
186
|
+
}
|
|
116
187
|
|
|
117
188
|
function clearScreen() {
|
|
118
189
|
if (process.stdout.isTTY) {
|
|
@@ -211,7 +282,7 @@ function renderConfigSummary(cfg, configPath, title = "CONFIG") {
|
|
|
211
282
|
const jitoTip = cfg.jito?.enabled ? cfg.jito.tip : "-";
|
|
212
283
|
const rows = [
|
|
213
284
|
["Config path", configPath],
|
|
214
|
-
["RPC URL", cfg.rpcUrl],
|
|
285
|
+
["RPC URL", formatConfigDisplayValue("rpcUrl", cfg.rpcUrl)],
|
|
215
286
|
["Slippage", cfg.slippage],
|
|
216
287
|
["Priority fee", cfg.priorityFee],
|
|
217
288
|
["Priority level", cfg.priorityFeeLevel],
|
|
@@ -252,7 +323,7 @@ async function promptSelect(rl, label, options, { current, required = false } =
|
|
|
252
323
|
|
|
253
324
|
async function promptNormalized(rl, label, key, { current, required = false } = {}) {
|
|
254
325
|
while (true) {
|
|
255
|
-
const suffix = current !== undefined ? ` [${
|
|
326
|
+
const suffix = current !== undefined ? ` [${formatConfigDisplayValue(key, current)}]` : "";
|
|
256
327
|
const answer = await askQuestion(rl, `${label}${suffix}: `);
|
|
257
328
|
if (!answer) {
|
|
258
329
|
if (required) {
|
|
@@ -589,7 +660,10 @@ configCmd
|
|
|
589
660
|
process.exit(1);
|
|
590
661
|
}
|
|
591
662
|
await saveConfig(cfg);
|
|
592
|
-
|
|
663
|
+
const displayValue = key.startsWith("jito.")
|
|
664
|
+
? toDisplayValue(cfg.jito?.[key.split(".")[1]])
|
|
665
|
+
: formatConfigDisplayValue(key, cfg[key]);
|
|
666
|
+
console.log(`✅ Updated ${key} → ${displayValue} in ${configPath}`);
|
|
593
667
|
renderConfigSummary(cfg, configPath);
|
|
594
668
|
});
|
|
595
669
|
|
|
@@ -646,9 +720,10 @@ program
|
|
|
646
720
|
"🔓 Private key already stored in Keychain. Would you like to replace it? (y/N): "
|
|
647
721
|
);
|
|
648
722
|
if (updateKey.toLowerCase() === "y") {
|
|
649
|
-
const privKey = await
|
|
723
|
+
const privKey = await askSecretQuestion(rl, "Paste your new private key: ");
|
|
650
724
|
await storePrivateKey(privKey);
|
|
651
725
|
console.log("🔐 Private key updated.");
|
|
726
|
+
printKeychainAccessHint();
|
|
652
727
|
} else {
|
|
653
728
|
console.log("✅ Keeping existing private key.");
|
|
654
729
|
}
|
|
@@ -658,9 +733,10 @@ program
|
|
|
658
733
|
"Would you like to store your private key in the macOS Keychain now? (y/N): "
|
|
659
734
|
);
|
|
660
735
|
if (storeKey.toLowerCase() === "y") {
|
|
661
|
-
const privKey = await
|
|
736
|
+
const privKey = await askSecretQuestion(rl, "Paste your private key: ");
|
|
662
737
|
await storePrivateKey(privKey);
|
|
663
738
|
console.log("🔐 Private key stored securely.");
|
|
739
|
+
printKeychainAccessHint();
|
|
664
740
|
} else {
|
|
665
741
|
console.log("⚠️ No private key stored. You can add one later with `summon keychain store`.");
|
|
666
742
|
}
|
|
@@ -696,21 +772,22 @@ const keychainCmd = program.command("keychain").description("Manage private key
|
|
|
696
772
|
keychainCmd
|
|
697
773
|
.command("store")
|
|
698
774
|
.description("Store private key securely in macOS Keychain")
|
|
699
|
-
.action(() => {
|
|
775
|
+
.action(async () => {
|
|
700
776
|
const rl = readline.createInterface({
|
|
701
777
|
input: process.stdin,
|
|
702
778
|
output: process.stdout,
|
|
703
779
|
});
|
|
704
|
-
|
|
780
|
+
try {
|
|
781
|
+
const input = await askSecretQuestion(rl, "Paste your wallet private key: ");
|
|
705
782
|
rl.close();
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
}
|
|
783
|
+
await storePrivateKey(input);
|
|
784
|
+
console.log("🔐 Private key securely stored in macOS Keychain.");
|
|
785
|
+
printKeychainAccessHint();
|
|
786
|
+
} catch (err) {
|
|
787
|
+
rl.close();
|
|
788
|
+
console.error("❌ Failed to store key:", err.message);
|
|
789
|
+
process.exitCode = 1;
|
|
790
|
+
}
|
|
714
791
|
});
|
|
715
792
|
|
|
716
793
|
keychainCmd
|