@xaidenlabs/uso 1.1.75 → 1.1.77
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xaidenlabs/uso",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.77",
|
|
4
4
|
"description": "Universal Solana Development Toolchain. Native or Stealth WSL Mode. Build, test, and deploy without the friction.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"uso": "bin/index.js"
|
|
@@ -10,7 +10,12 @@
|
|
|
10
10
|
"src",
|
|
11
11
|
"templates",
|
|
12
12
|
"anchor_program",
|
|
13
|
-
"anchor_project"
|
|
13
|
+
"anchor_project/Anchor.toml",
|
|
14
|
+
"anchor_project/package.json",
|
|
15
|
+
"anchor_project/tsconfig.json",
|
|
16
|
+
"anchor_project/programs/uso_verifier/Cargo.toml",
|
|
17
|
+
"anchor_project/programs/uso_verifier/src",
|
|
18
|
+
"anchor_project/tests"
|
|
14
19
|
],
|
|
15
20
|
"scripts": {
|
|
16
21
|
"test": "echo \"Error: no test specified\" && exit 1"
|
package/src/commands/verify.js
CHANGED
|
@@ -1,212 +1,254 @@
|
|
|
1
|
-
const shell = require(
|
|
2
|
-
const path = require(
|
|
3
|
-
const fs = require(
|
|
4
|
-
const os = require(
|
|
5
|
-
const readline = require(
|
|
6
|
-
const { log, spinner } = require(
|
|
7
|
-
const {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
const shell = require("shelljs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const os = require("os");
|
|
5
|
+
const readline = require("readline");
|
|
6
|
+
const { log, spinner } = require("../utils/logger");
|
|
7
|
+
const {
|
|
8
|
+
ensureWalletInteractive,
|
|
9
|
+
resolveSolanaKeygen,
|
|
10
|
+
} = require("../utils/wallet");
|
|
11
|
+
const { getCargoBinPath } = require("../utils/paths");
|
|
12
|
+
const { isStealthMode } = require("../utils/stealth");
|
|
13
|
+
const { runWsl, toWslPath } = require("../utils/wsl-bridge");
|
|
11
14
|
|
|
12
15
|
const getSolanaBin = () => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
if (shell.which("solana")) return "solana";
|
|
17
|
+
if (os.platform() === "win32") {
|
|
18
|
+
const defaultPath = path.join(
|
|
19
|
+
os.homedir(),
|
|
20
|
+
".local",
|
|
21
|
+
"share",
|
|
22
|
+
"solana",
|
|
23
|
+
"install",
|
|
24
|
+
"active_release",
|
|
25
|
+
"bin",
|
|
26
|
+
"solana.exe",
|
|
27
|
+
);
|
|
28
|
+
if (fs.existsSync(defaultPath)) return `"${defaultPath}"`;
|
|
29
|
+
}
|
|
30
|
+
return "solana";
|
|
19
31
|
};
|
|
20
32
|
|
|
21
33
|
const getAnchorBin = () => {
|
|
22
|
-
|
|
23
|
-
|
|
34
|
+
if (shell.which("anchor")) return "anchor";
|
|
35
|
+
return "anchor";
|
|
24
36
|
};
|
|
25
37
|
|
|
26
38
|
const askBuildConfirmation = async () => {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
39
|
+
const rl = readline.createInterface({
|
|
40
|
+
input: process.stdin,
|
|
41
|
+
output: process.stdout,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return new Promise((resolve) => {
|
|
45
|
+
log.info("");
|
|
46
|
+
log.info(
|
|
47
|
+
"ℹ️ The next step verifies your toolchain by building a real project.",
|
|
48
|
+
);
|
|
49
|
+
log.warn(
|
|
50
|
+
"⚠️ NOTE: If this is your first time, it will download ~200MB of platform tools.",
|
|
51
|
+
);
|
|
52
|
+
log.warn(" This can take 5-10 minutes depending on your internet.");
|
|
53
|
+
|
|
54
|
+
rl.question(
|
|
55
|
+
"👉 Do you want to proceed with the full build verification? [Y/n] ",
|
|
56
|
+
(answer) => {
|
|
57
|
+
rl.close();
|
|
58
|
+
const a = answer.toLowerCase();
|
|
59
|
+
if (a === "n" || a === "no") {
|
|
60
|
+
resolve(false);
|
|
61
|
+
} else {
|
|
62
|
+
resolve(true);
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
);
|
|
66
|
+
});
|
|
48
67
|
};
|
|
49
68
|
|
|
50
69
|
const verify = async () => {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
70
|
+
log.header("🧪 Verifying Solana Setup...");
|
|
71
|
+
|
|
72
|
+
const anchorCmd = getAnchorBin();
|
|
73
|
+
|
|
74
|
+
// 1. Check/Create Wallet
|
|
75
|
+
const walletReady = await ensureWalletInteractive();
|
|
76
|
+
|
|
77
|
+
if (!walletReady) {
|
|
78
|
+
log.error("❌ Verification cancelled. A wallet is required to build/test.");
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Fix PATH for cargo-build-sbf logic (Windows)
|
|
83
|
+
if (os.platform() === "win32") {
|
|
84
|
+
const solanaBase = path.join(
|
|
85
|
+
os.homedir(),
|
|
86
|
+
".local",
|
|
87
|
+
"share",
|
|
88
|
+
"solana",
|
|
89
|
+
"install",
|
|
90
|
+
);
|
|
91
|
+
const activeRelease = path.join(solanaBase, "active_release");
|
|
92
|
+
const activeBin = path.join(activeRelease, "bin");
|
|
93
|
+
|
|
94
|
+
let realBin = activeBin;
|
|
95
|
+
try {
|
|
96
|
+
if (fs.existsSync(activeRelease)) {
|
|
97
|
+
const realRelease = fs.realpathSync(activeRelease);
|
|
98
|
+
realBin = path.join(realRelease, "bin");
|
|
99
|
+
}
|
|
100
|
+
} catch (e) {}
|
|
101
|
+
|
|
102
|
+
const pathsToAdd = [activeBin];
|
|
103
|
+
if (realBin !== activeBin) pathsToAdd.push(realBin);
|
|
104
|
+
|
|
105
|
+
let pathKey = "PATH";
|
|
106
|
+
for (const key of Object.keys(process.env)) {
|
|
107
|
+
if (key.toUpperCase() === "PATH") {
|
|
108
|
+
pathKey = key;
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
61
111
|
}
|
|
62
112
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const solanaBase = path.join(os.homedir(), '.local', 'share', 'solana', 'install');
|
|
66
|
-
const activeRelease = path.join(solanaBase, 'active_release');
|
|
67
|
-
const activeBin = path.join(activeRelease, 'bin');
|
|
68
|
-
|
|
69
|
-
let realBin = activeBin;
|
|
70
|
-
try {
|
|
71
|
-
if (fs.existsSync(activeRelease)) {
|
|
72
|
-
const realRelease = fs.realpathSync(activeRelease);
|
|
73
|
-
realBin = path.join(realRelease, 'bin');
|
|
74
|
-
}
|
|
75
|
-
} catch (e) { }
|
|
76
|
-
|
|
77
|
-
const pathsToAdd = [activeBin];
|
|
78
|
-
if (realBin !== activeBin) pathsToAdd.push(realBin);
|
|
79
|
-
|
|
80
|
-
let pathKey = 'PATH';
|
|
81
|
-
for (const key of Object.keys(process.env)) {
|
|
82
|
-
if (key.toUpperCase() === 'PATH') {
|
|
83
|
-
pathKey = key;
|
|
84
|
-
break;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
let currentPath = process.env[pathKey] || '';
|
|
89
|
-
let modified = false;
|
|
90
|
-
|
|
91
|
-
pathsToAdd.forEach(p => {
|
|
92
|
-
if (fs.existsSync(p) && !currentPath.includes(p)) {
|
|
93
|
-
currentPath = `${p};${currentPath}`;
|
|
94
|
-
modified = true;
|
|
95
|
-
}
|
|
96
|
-
});
|
|
113
|
+
let currentPath = process.env[pathKey] || "";
|
|
114
|
+
let modified = false;
|
|
97
115
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
116
|
+
pathsToAdd.forEach((p) => {
|
|
117
|
+
if (fs.existsSync(p) && !currentPath.includes(p)) {
|
|
118
|
+
currentPath = `${p};${currentPath}`;
|
|
119
|
+
modified = true;
|
|
120
|
+
}
|
|
121
|
+
});
|
|
103
122
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
log.info("\n⏭️ Skipping build verification.");
|
|
108
|
-
log.success("✅ Basic tools are installed.");
|
|
109
|
-
log.info("👉 You can run 'npx uso doctor' for a quick version check.");
|
|
110
|
-
return;
|
|
123
|
+
if (modified) {
|
|
124
|
+
process.env[pathKey] = currentPath;
|
|
125
|
+
log.success("✅ Solana bin temporarily added to PATH.");
|
|
111
126
|
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// 2. Ask for confirmation before building
|
|
130
|
+
const proceed = await askBuildConfirmation();
|
|
131
|
+
if (!proceed) {
|
|
132
|
+
log.info("\n⏭️ Skipping build verification.");
|
|
133
|
+
log.success("✅ Basic tools are installed.");
|
|
134
|
+
log.info("👉 You can run 'npx uso doctor' for a quick version check.");
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// 3. Build Project
|
|
139
|
+
log.info("🔨 Building verification project...");
|
|
140
|
+
|
|
141
|
+
const templateDir = path.resolve(__dirname, "../../anchor_project");
|
|
142
|
+
const tempDir = path.join(os.tmpdir(), "uso-verification-" + Date.now());
|
|
143
|
+
const stealth = isStealthMode();
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
shell.cp("-R", templateDir, tempDir);
|
|
147
|
+
|
|
148
|
+
let attempts = 0;
|
|
149
|
+
const maxAttempts = 3;
|
|
150
|
+
let success = false;
|
|
151
|
+
let finalError = "";
|
|
152
|
+
|
|
153
|
+
while (attempts < maxAttempts && !success) {
|
|
154
|
+
attempts++;
|
|
155
|
+
if (attempts > 1) {
|
|
156
|
+
log.warn(`⚠️ Retrying build (Attempt ${attempts}/${maxAttempts})...`);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
let buildResult;
|
|
160
|
+
|
|
161
|
+
if (stealth.enabled) {
|
|
162
|
+
// Convert Windows path to WSL path
|
|
163
|
+
const wslProjectPath = toWslPath(tempDir);
|
|
164
|
+
|
|
165
|
+
// Run anchor build in WSL
|
|
166
|
+
const buildCmd = `source $HOME/.cargo/env 2>/dev/null && cd "${wslProjectPath}" && anchor build`;
|
|
167
|
+
buildResult = runWsl(buildCmd, {
|
|
168
|
+
distro: stealth.distro,
|
|
169
|
+
execOpts: { silent: false },
|
|
170
|
+
});
|
|
171
|
+
} else {
|
|
172
|
+
buildResult = shell.exec(`cd "${tempDir}" && ${anchorCmd} build`, {
|
|
173
|
+
silent: false,
|
|
174
|
+
env: process.env,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
112
177
|
|
|
113
|
-
|
|
114
|
-
|
|
178
|
+
success = buildResult.code === 0;
|
|
179
|
+
let stderr = buildResult.stderr + buildResult.stdout;
|
|
115
180
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
const stealth = isStealthMode();
|
|
181
|
+
if (!success) {
|
|
182
|
+
finalError = stderr;
|
|
119
183
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
while (attempts < maxAttempts && !success) {
|
|
129
|
-
attempts++;
|
|
130
|
-
if (attempts > 1) {
|
|
131
|
-
log.warn(`⚠️ Retrying build (Attempt ${attempts}/${maxAttempts})...`);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
let buildResult;
|
|
135
|
-
|
|
136
|
-
if (stealth.enabled) {
|
|
137
|
-
// Convert Windows path to WSL path
|
|
138
|
-
const wslProjectPath = toWslPath(tempDir);
|
|
139
|
-
|
|
140
|
-
// Run anchor build in WSL
|
|
141
|
-
const buildCmd = `source $HOME/.cargo/env 2>/dev/null && cd "${wslProjectPath}" && anchor build`;
|
|
142
|
-
buildResult = runWsl(buildCmd, {
|
|
143
|
-
distro: stealth.distro,
|
|
144
|
-
execOpts: { silent: false }
|
|
145
|
-
});
|
|
146
|
-
} else {
|
|
147
|
-
buildResult = shell.exec(`cd "${tempDir}" && ${anchorCmd} build`, {
|
|
148
|
-
silent: false,
|
|
149
|
-
env: process.env
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
success = buildResult.code === 0;
|
|
154
|
-
let stderr = buildResult.stderr + buildResult.stdout;
|
|
155
|
-
|
|
156
|
-
if (!success) {
|
|
157
|
-
finalError = stderr;
|
|
158
|
-
|
|
159
|
-
if (stderr.includes('TimedOut') || stderr.includes('reqwest::Error') || stderr.includes('Failed to install platform-tools')) {
|
|
160
|
-
log.warn(`⚠️ Network timeout detected. Retrying...`);
|
|
161
|
-
continue;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
if (!stealth.enabled && os.platform() === 'win32' && stderr.includes('os error 1314')) {
|
|
165
|
-
log.warn("⚠️ Privilege error detected (os error 1314).");
|
|
166
|
-
log.info("ℹ️ First-time Solana build requires Administrator privileges to install tools.");
|
|
167
|
-
log.info("🛡️ Retrying with Elevated Permissions (Please accept UAC prompt)...");
|
|
168
|
-
|
|
169
|
-
let absAnchor = anchorCmd;
|
|
170
|
-
if (anchorCmd === 'anchor') {
|
|
171
|
-
if (shell.which('anchor')) absAnchor = shell.which('anchor').toString();
|
|
172
|
-
else absAnchor = path.join(getCargoBinPath(), 'anchor.exe');
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const psCommand = `cd '${tempDir}'; & '${absAnchor}' build; if ($LASTEXITCODE -ne 0) { Read-Host 'Build Failed. Press Enter to exit...' }`;
|
|
176
|
-
const elevateCmd = `powershell -Command "Start-Process powershell -ArgumentList \\"-NoExit\\", \\"-Command\\", \\"${psCommand.replace(/"/g, '\\`"')}\\" -Verb RunAs -Wait"`;
|
|
177
|
-
|
|
178
|
-
shell.exec(elevateCmd);
|
|
179
|
-
|
|
180
|
-
const idlPath = path.join(tempDir, 'target', 'idl', 'uso_verifier.json');
|
|
181
|
-
if (fs.existsSync(idlPath)) {
|
|
182
|
-
success = true;
|
|
183
|
-
log.success("✅ Elevated build passed.");
|
|
184
|
-
} else {
|
|
185
|
-
log.error("❌ Elevated build failed or was cancelled.");
|
|
186
|
-
break;
|
|
187
|
-
}
|
|
188
|
-
} else {
|
|
189
|
-
break;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
184
|
+
if (
|
|
185
|
+
stderr.includes("TimedOut") ||
|
|
186
|
+
stderr.includes("reqwest::Error") ||
|
|
187
|
+
stderr.includes("Failed to install platform-tools")
|
|
188
|
+
) {
|
|
189
|
+
log.warn(`⚠️ Network timeout detected. Retrying...`);
|
|
190
|
+
continue;
|
|
192
191
|
}
|
|
193
192
|
|
|
194
|
-
if (
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
193
|
+
if (
|
|
194
|
+
!stealth.enabled &&
|
|
195
|
+
os.platform() === "win32" &&
|
|
196
|
+
stderr.includes("os error 1314")
|
|
197
|
+
) {
|
|
198
|
+
log.warn("⚠️ Privilege error detected (os error 1314).");
|
|
199
|
+
log.info(
|
|
200
|
+
"ℹ️ First-time Solana build requires Administrator privileges to install tools.",
|
|
201
|
+
);
|
|
202
|
+
log.info(
|
|
203
|
+
"🛡️ Retrying with Elevated Permissions (Please accept UAC prompt)...",
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
let absAnchor = anchorCmd;
|
|
207
|
+
if (anchorCmd === "anchor") {
|
|
208
|
+
if (shell.which("anchor"))
|
|
209
|
+
absAnchor = shell.which("anchor").toString();
|
|
210
|
+
else absAnchor = path.join(getCargoBinPath(), "anchor.exe");
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const psCommand = `cd '${tempDir}'; & '${absAnchor}' build; if ($LASTEXITCODE -ne 0) { Read-Host 'Build Failed. Press Enter to exit...' }`;
|
|
214
|
+
const elevateCmd = `powershell -Command "Start-Process powershell -ArgumentList \\"-NoExit\\", \\"-Command\\", \\"${psCommand.replace(/"/g, '\\`"')}\\" -Verb RunAs -Wait"`;
|
|
215
|
+
|
|
216
|
+
shell.exec(elevateCmd);
|
|
217
|
+
|
|
218
|
+
const idlPath = path.join(
|
|
219
|
+
tempDir,
|
|
220
|
+
"target",
|
|
221
|
+
"idl",
|
|
222
|
+
"uso_verifier.json",
|
|
223
|
+
);
|
|
224
|
+
if (fs.existsSync(idlPath)) {
|
|
225
|
+
success = true;
|
|
226
|
+
log.success("✅ Elevated build passed.");
|
|
227
|
+
} else {
|
|
228
|
+
log.error("❌ Elevated build failed or was cancelled.");
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
201
231
|
} else {
|
|
202
|
-
|
|
232
|
+
break;
|
|
203
233
|
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
204
236
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
237
|
+
if (success) {
|
|
238
|
+
log.success("✅ Verification Successful!");
|
|
239
|
+
log.success("🎉 Your Solana environment is fully operational.");
|
|
240
|
+
log.info(" - Rust is working");
|
|
241
|
+
log.info(" - Solana CLI is working");
|
|
242
|
+
log.info(" - Anchor is working");
|
|
243
|
+
log.info(" - Wallet is configured");
|
|
244
|
+
} else {
|
|
245
|
+
log.error("❌ Verification Failed.");
|
|
209
246
|
}
|
|
247
|
+
} catch (err) {
|
|
248
|
+
log.error("❌ Verification Error: " + err.message);
|
|
249
|
+
} finally {
|
|
250
|
+
shell.rm("-rf", tempDir);
|
|
251
|
+
}
|
|
210
252
|
};
|
|
211
253
|
|
|
212
254
|
module.exports = { verify };
|
package/src/utils/wallet.js
CHANGED
|
@@ -85,10 +85,14 @@ const ensureWalletInteractive = async () => {
|
|
|
85
85
|
if (stealth.enabled) {
|
|
86
86
|
// Create wallet inside WSL
|
|
87
87
|
const { spawnSync } = require("child_process");
|
|
88
|
-
|
|
88
|
+
|
|
89
89
|
// Use a login shell (-l) to load full environment, then create wallet
|
|
90
90
|
const wslCmd = `mkdir -p "$HOME/.config/solana" && solana-keygen new --outfile "$HOME/.config/solana/id.json"`;
|
|
91
|
-
const result = spawnSync(
|
|
91
|
+
const result = spawnSync(
|
|
92
|
+
"wsl",
|
|
93
|
+
["-d", stealth.distro, "-e", "bash", "-l", "-c", wslCmd],
|
|
94
|
+
{ stdio: "inherit" },
|
|
95
|
+
);
|
|
92
96
|
|
|
93
97
|
// Verify wallet was created in WSL
|
|
94
98
|
const verifyCmd = runWsl(
|