traderclaw-cli 1.0.62 → 1.0.65
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/bin/installer-step-engine.mjs +12 -1
- package/bin/openclaw-trader.mjs +88 -15
- package/package.json +2 -2
|
@@ -1303,7 +1303,12 @@ function resolveLlmModelSelection(provider, requestedModel) {
|
|
|
1303
1303
|
return { model: chosen || availableModels[0], source: "provider_default", availableModels, warnings };
|
|
1304
1304
|
}
|
|
1305
1305
|
|
|
1306
|
-
warnings.push(
|
|
1306
|
+
warnings.push(
|
|
1307
|
+
`[ALERT] No discoverable model list found for provider '${provider}'. ` +
|
|
1308
|
+
`Auto-selecting hardcoded default '${fallbackModelForProvider(provider)}' — ` +
|
|
1309
|
+
`this model will be billed to your API key. ` +
|
|
1310
|
+
`To use a different model, after finishing setup, use openclaw config and set the model manually.`,
|
|
1311
|
+
);
|
|
1307
1312
|
return { model: fallbackModelForProvider(provider), source: "fallback_guess", availableModels, warnings };
|
|
1308
1313
|
}
|
|
1309
1314
|
|
|
@@ -1503,6 +1508,7 @@ export class InstallerStepEngine {
|
|
|
1503
1508
|
xAccessTokenCtoSecret: typeof options.xAccessTokenCtoSecret === "string" ? options.xAccessTokenCtoSecret : "",
|
|
1504
1509
|
xAccessTokenIntern: typeof options.xAccessTokenIntern === "string" ? options.xAccessTokenIntern : "",
|
|
1505
1510
|
xAccessTokenInternSecret: typeof options.xAccessTokenInternSecret === "string" ? options.xAccessTokenInternSecret : "",
|
|
1511
|
+
referralCode: typeof options.referralCode === "string" ? options.referralCode.trim() : "",
|
|
1506
1512
|
};
|
|
1507
1513
|
this.hooks = {
|
|
1508
1514
|
onStepEvent: typeof hooks.onStepEvent === "function" ? hooks.onStepEvent : () => {},
|
|
@@ -1788,6 +1794,11 @@ export class InstallerStepEngine {
|
|
|
1788
1794
|
args.push("--gateway-base-url", gatewayBaseUrl);
|
|
1789
1795
|
}
|
|
1790
1796
|
|
|
1797
|
+
const ref = String(this.options.referralCode || "").trim();
|
|
1798
|
+
if (ref) {
|
|
1799
|
+
args.push("--referral-code", ref);
|
|
1800
|
+
}
|
|
1801
|
+
|
|
1791
1802
|
const command = [this.modeConfig.cliName, ...args].join(" ");
|
|
1792
1803
|
const docs =
|
|
1793
1804
|
"https://docs.traderclaw.ai/docs/installation#troubleshooting-session-expired-auth-errors-or-the-agent-logged-out";
|
package/bin/openclaw-trader.mjs
CHANGED
|
@@ -14,18 +14,19 @@ import { resolvePluginPackageRoot } from "./resolve-plugin-root.mjs";
|
|
|
14
14
|
|
|
15
15
|
const execFileAsync = promisify(execFile);
|
|
16
16
|
|
|
17
|
-
/**
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Fast wizard catalog lookup: prefer one full list, then only probe key providers.
|
|
19
|
+
* Timeouts are intentionally short — on a fresh install the CLI can't reach providers
|
|
20
|
+
* (no credentials yet) so we want to fail fast and show the curated fallback list
|
|
21
|
+
* rather than making the user wait 10+ seconds. Target total: ≤ 5 s.
|
|
22
|
+
*/
|
|
23
|
+
const OPENCLAW_MODELS_FLAT_TIMEOUT_MS = 3_000;
|
|
24
|
+
const OPENCLAW_MODELS_PER_PROVIDER_TIMEOUT_MS = 2_500;
|
|
20
25
|
const WIZARD_PRIORITY_PROVIDERS = [
|
|
21
26
|
"anthropic",
|
|
22
27
|
"openai",
|
|
23
|
-
"openrouter",
|
|
24
28
|
"google",
|
|
25
|
-
"
|
|
26
|
-
"deepseek",
|
|
27
|
-
"groq",
|
|
28
|
-
"mistral",
|
|
29
|
+
"openrouter",
|
|
29
30
|
];
|
|
30
31
|
const WIZARD_PROVIDER_PRIORITY = [
|
|
31
32
|
...WIZARD_PRIORITY_PROVIDERS,
|
|
@@ -520,15 +521,22 @@ function signChallengeLocally(challengeText, privateKeyBase58) {
|
|
|
520
521
|
return b58Encode(new Uint8Array(sig));
|
|
521
522
|
}
|
|
522
523
|
|
|
523
|
-
async function doSignup(orchestratorUrl, externalUserId) {
|
|
524
|
+
async function doSignup(orchestratorUrl, externalUserId, referralCode = "") {
|
|
524
525
|
printInfo(` Signing up as: ${externalUserId}`);
|
|
526
|
+
const body = { externalUserId };
|
|
527
|
+
const ref = String(referralCode || "").trim();
|
|
528
|
+
if (ref) body.referralCode = ref;
|
|
525
529
|
const res = await httpRequest(`${orchestratorUrl}/api/auth/signup`, {
|
|
526
530
|
method: "POST",
|
|
527
|
-
body
|
|
531
|
+
body,
|
|
528
532
|
});
|
|
529
533
|
|
|
530
534
|
if (!res.ok) {
|
|
531
|
-
|
|
535
|
+
const payload = res.data && typeof res.data === "object" ? res.data : {};
|
|
536
|
+
const apiMsg = typeof payload.message === "string" ? payload.message : JSON.stringify(res.data);
|
|
537
|
+
const err = new Error(`Signup failed (HTTP ${res.status}): ${apiMsg}`);
|
|
538
|
+
if (typeof payload.code === "string") err.code = payload.code;
|
|
539
|
+
throw err;
|
|
532
540
|
}
|
|
533
541
|
|
|
534
542
|
return res.data;
|
|
@@ -700,6 +708,8 @@ async function cmdSetup(args) {
|
|
|
700
708
|
let noEnsureGatewayPersistent = false;
|
|
701
709
|
let signupRecoverySecret = undefined;
|
|
702
710
|
let forwardTelegramRecipientArg = "";
|
|
711
|
+
let referralCodeArg = "";
|
|
712
|
+
let referralInvalidRetries = 0;
|
|
703
713
|
|
|
704
714
|
for (let i = 0; i < args.length; i++) {
|
|
705
715
|
if ((args[i] === "--api-key" || args[i] === "-k") && args[i + 1]) {
|
|
@@ -746,6 +756,9 @@ async function cmdSetup(args) {
|
|
|
746
756
|
) {
|
|
747
757
|
forwardTelegramRecipientArg = args[++i];
|
|
748
758
|
}
|
|
759
|
+
if ((args[i] === "--referral-code" || args[i] === "-r") && args[i + 1]) {
|
|
760
|
+
referralCodeArg = args[++i];
|
|
761
|
+
}
|
|
749
762
|
}
|
|
750
763
|
const runtimeWalletPrivateKey = getRuntimeWalletPrivateKey(walletPrivateKey);
|
|
751
764
|
|
|
@@ -763,6 +776,16 @@ async function cmdSetup(args) {
|
|
|
763
776
|
}
|
|
764
777
|
}
|
|
765
778
|
|
|
779
|
+
if (doSignupFlow && !referralCodeArg) {
|
|
780
|
+
printInfo(
|
|
781
|
+
"\n Optional: enter a referral code for bonus access time (24h extra when valid). Press Enter to skip.\n",
|
|
782
|
+
);
|
|
783
|
+
printInfo(
|
|
784
|
+
" Benefits: extra trial time now; referring others later earns +8h per user who completes at least one trade with the agent.\n",
|
|
785
|
+
);
|
|
786
|
+
referralCodeArg = await prompt("Referral code (optional)", "");
|
|
787
|
+
}
|
|
788
|
+
|
|
766
789
|
if (doSignupFlow) {
|
|
767
790
|
print("\n Signing up for a new account...\n");
|
|
768
791
|
if (!externalUserId) {
|
|
@@ -771,7 +794,7 @@ async function cmdSetup(args) {
|
|
|
771
794
|
|
|
772
795
|
for (let signupAttempt = 0; ; signupAttempt++) {
|
|
773
796
|
try {
|
|
774
|
-
const signupResult = await doSignup(orchestratorUrl, externalUserId);
|
|
797
|
+
const signupResult = await doSignup(orchestratorUrl, externalUserId, referralCodeArg);
|
|
775
798
|
apiKey = signupResult.apiKey;
|
|
776
799
|
if (signupResult.recoverySecret) {
|
|
777
800
|
signupRecoverySecret = signupResult.recoverySecret;
|
|
@@ -783,6 +806,22 @@ async function cmdSetup(args) {
|
|
|
783
806
|
break;
|
|
784
807
|
} catch (err) {
|
|
785
808
|
const msg = err.message || String(err);
|
|
809
|
+
const apiCode = err.code;
|
|
810
|
+
const referralRejected =
|
|
811
|
+
apiCode === "REFERRAL_CODE_INVALID" ||
|
|
812
|
+
msg.includes("REFERRAL_CODE_INVALID") ||
|
|
813
|
+
msg.includes("Unknown referral code");
|
|
814
|
+
if (referralRejected) {
|
|
815
|
+
referralInvalidRetries += 1;
|
|
816
|
+
if (referralInvalidRetries > 30) {
|
|
817
|
+
printError("Too many invalid referral attempts. Aborting.");
|
|
818
|
+
process.exit(1);
|
|
819
|
+
}
|
|
820
|
+
printWarn(" That referral code was not accepted (unknown or invalid).");
|
|
821
|
+
printInfo(" Leave it blank or enter a different code, then try again.");
|
|
822
|
+
referralCodeArg = await prompt("Referral code (optional, leave empty to skip)", "");
|
|
823
|
+
continue;
|
|
824
|
+
}
|
|
786
825
|
if (msg.includes("SIGNUP_ALREADY_COMPLETED") || msg.includes("409")) {
|
|
787
826
|
printWarn(` User "${externalUserId}" is already registered.`);
|
|
788
827
|
if (signupAttempt >= 2) {
|
|
@@ -2176,6 +2215,7 @@ function wizardHtml(defaults) {
|
|
|
2176
2215
|
.spinner { width:14px; height:14px; border:2px solid #334a87; border-top-color:#8daeff; border-radius:50%; animation:spin 0.8s linear infinite; flex:0 0 auto; }
|
|
2177
2216
|
.muted a { color:#9fd3ff; }
|
|
2178
2217
|
.muted a:hover { color:#c5e5ff; }
|
|
2218
|
+
.info-dot { display:inline-flex; align-items:center; justify-content:center; width:18px; height:18px; border-radius:50%; background:#22315a; color:#9cb0de; font-size:11px; font-weight:700; cursor:help; flex-shrink:0; }
|
|
2179
2219
|
@keyframes spin { to { transform:rotate(360deg); } }
|
|
2180
2220
|
</style>
|
|
2181
2221
|
</head>
|
|
@@ -2253,6 +2293,13 @@ function wizardHtml(defaults) {
|
|
|
2253
2293
|
<p class="muted">Already have a TraderClaw account? Paste your API key here. New users: leave empty.</p>
|
|
2254
2294
|
</div>
|
|
2255
2295
|
</div>
|
|
2296
|
+
<div style="margin-top:12px;">
|
|
2297
|
+
<label style="display:flex;align-items:center;gap:8px;">Referral code (optional)
|
|
2298
|
+
<span class="info-dot" title="Included access: 24 hours for every new account. Add a valid referral code for an extra 24 hours. Refer others: when they complete at least one trade with the agent, you earn +8 hours per active referral. When your access window ends, you will need to stake or keep referring to continue.">i</span>
|
|
2299
|
+
</label>
|
|
2300
|
+
<input id="referralCode" type="text" maxlength="16" autocomplete="off" placeholder="e.g. ABCD1234" />
|
|
2301
|
+
<p class="muted">If you have a friend’s code, enter it here. The setup command below will include it for <code>traderclaw setup</code>. If the server rejects the code, clear this field or fix it and copy the updated command — or run <code>traderclaw setup</code> again and enter a valid code or leave referral blank when prompted.</p>
|
|
2302
|
+
</div>
|
|
2256
2303
|
<button id="start" disabled>Start Installation</button>
|
|
2257
2304
|
</div>
|
|
2258
2305
|
<div class="card" id="statusCard">
|
|
@@ -2361,6 +2408,7 @@ function wizardHtml(defaults) {
|
|
|
2361
2408
|
let llmLoadStartedAt = 0;
|
|
2362
2409
|
let announcedTailscaleUrl = "";
|
|
2363
2410
|
let announcedFunnelAdminUrl = "";
|
|
2411
|
+
let lastReferralFailFingerprint = "";
|
|
2364
2412
|
let pollTimer = null;
|
|
2365
2413
|
let pollIntervalMs = 1200;
|
|
2366
2414
|
let installLocked = false;
|
|
@@ -2551,10 +2599,11 @@ function wizardHtml(defaults) {
|
|
|
2551
2599
|
|
|
2552
2600
|
const payload = {
|
|
2553
2601
|
llmProvider: llmProviderEl.value.trim(),
|
|
2554
|
-
llmModel:
|
|
2602
|
+
llmModel: llmModelEl.value.trim(),
|
|
2555
2603
|
llmCredential: llmCredentialEl.value.trim(),
|
|
2556
2604
|
apiKey: document.getElementById("apiKey").value.trim(),
|
|
2557
2605
|
telegramToken: document.getElementById("telegramToken").value.trim(),
|
|
2606
|
+
referralCode: document.getElementById("referralCode").value.trim(),
|
|
2558
2607
|
xConsumerKey: xConsumerKeyEl.value.trim(),
|
|
2559
2608
|
xConsumerSecret: xConsumerSecretEl.value.trim(),
|
|
2560
2609
|
xAccessTokenMain: xAccessTokenMainEl.value.trim(),
|
|
@@ -2716,9 +2765,30 @@ function wizardHtml(defaults) {
|
|
|
2716
2765
|
}
|
|
2717
2766
|
|
|
2718
2767
|
const errors = data.errors || [];
|
|
2719
|
-
|
|
2768
|
+
let manualText = errors.length > 0
|
|
2720
2769
|
? errors.map((e) => "Step " + (e.stepId || "unknown") + ":\\n" + (e.error || "")).join("\\n\\n")
|
|
2721
2770
|
: "";
|
|
2771
|
+
const combinedErr = errors.map((e) => e.error || "").join("\\n");
|
|
2772
|
+
if (
|
|
2773
|
+
data.status === "failed"
|
|
2774
|
+
&& /REFERRAL_CODE_INVALID|Unknown referral code/i.test(combinedErr)
|
|
2775
|
+
) {
|
|
2776
|
+
manualText +=
|
|
2777
|
+
(manualText ? "\\n\\n" : "") +
|
|
2778
|
+
"Referral code was rejected. Clear or fix the referral field above, then click Start Installation again.";
|
|
2779
|
+
const fp = combinedErr.slice(0, 240);
|
|
2780
|
+
if (fp && fp !== lastReferralFailFingerprint) {
|
|
2781
|
+
lastReferralFailFingerprint = fp;
|
|
2782
|
+
try {
|
|
2783
|
+
window.alert(
|
|
2784
|
+
"Referral code was not accepted. Update or clear the referral field, then click Start Installation again.",
|
|
2785
|
+
);
|
|
2786
|
+
} catch {
|
|
2787
|
+
/* ignore */
|
|
2788
|
+
}
|
|
2789
|
+
}
|
|
2790
|
+
}
|
|
2791
|
+
manualEl.textContent = manualText;
|
|
2722
2792
|
stepsEl.innerHTML = "";
|
|
2723
2793
|
steps.forEach((row) => {
|
|
2724
2794
|
const tr = document.createElement("tr");
|
|
@@ -2938,6 +3008,7 @@ async function cmdInstall(args) {
|
|
|
2938
3008
|
enableTelegram: true,
|
|
2939
3009
|
telegramToken: body.telegramToken || defaults.telegramToken,
|
|
2940
3010
|
autoInstallDeps: true,
|
|
3011
|
+
referralCode: typeof body.referralCode === "string" ? body.referralCode.trim() : "",
|
|
2941
3012
|
xConsumerKey: body.xConsumerKey ?? defaults.xConsumerKey,
|
|
2942
3013
|
xConsumerSecret: body.xConsumerSecret ?? defaults.xConsumerSecret,
|
|
2943
3014
|
xAccessTokenMain: body.xAccessTokenMain ?? defaults.xAccessTokenMain,
|
|
@@ -2973,6 +3044,7 @@ async function cmdInstall(args) {
|
|
|
2973
3044
|
enableTelegram: true,
|
|
2974
3045
|
telegramToken: body.telegramToken || defaults.telegramToken,
|
|
2975
3046
|
autoInstallDeps: true,
|
|
3047
|
+
referralCode: wizardOpts.referralCode,
|
|
2976
3048
|
xConsumerKey: wizardOpts.xConsumerKey,
|
|
2977
3049
|
xConsumerSecret: wizardOpts.xConsumerSecret,
|
|
2978
3050
|
xAccessTokenMain: wizardOpts.xAccessTokenMain,
|
|
@@ -3311,6 +3383,7 @@ Setup options:
|
|
|
3311
3383
|
--gateway-base-url, -g Gateway public HTTPS URL for orchestrator callbacks
|
|
3312
3384
|
--gateway-token, -t Gateway bearer token (defaults to API key)
|
|
3313
3385
|
--telegram-recipient Telegram @username or chat id (aliases: --forward-telegram-chat-id, --telegram-chat-id)
|
|
3386
|
+
--referral-code, -r Optional referral code for new signups (extra trial time when valid)
|
|
3314
3387
|
--skip-gateway-registration Skip gateway URL registration with orchestrator
|
|
3315
3388
|
--show-api-key Extra hint after signup (full key is always shown once; confirm with API_KEY_STORED)
|
|
3316
3389
|
--show-wallet-private-key Reveal full wallet private key in setup output
|
|
@@ -3340,7 +3413,7 @@ Examples:
|
|
|
3340
3413
|
traderclaw install --wizard
|
|
3341
3414
|
traderclaw install --wizard --lane quick-local
|
|
3342
3415
|
traderclaw gateway ensure-persistent
|
|
3343
|
-
traderclaw setup --signup --user-id my_agent_001
|
|
3416
|
+
traderclaw setup --signup --user-id my_agent_001 --referral-code ABCD1234
|
|
3344
3417
|
traderclaw setup --api-key oc_xxx --url https://api.traderclaw.ai
|
|
3345
3418
|
traderclaw setup --gateway-base-url https://gateway.myhost.ts.net
|
|
3346
3419
|
traderclaw setup --telegram-recipient @myusername
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "traderclaw-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.65",
|
|
4
4
|
"description": "Global TraderClaw CLI (install --wizard, setup, precheck). Installs solana-traderclaw as a dependency for OpenClaw plugin files.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"node": ">=22"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"solana-traderclaw": "^1.0.
|
|
20
|
+
"solana-traderclaw": "^1.0.65"
|
|
21
21
|
},
|
|
22
22
|
"keywords": [
|
|
23
23
|
"traderclaw",
|