traderclaw-cli 1.0.61 → 1.0.63
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 +11 -0
- package/bin/openclaw-trader.mjs +85 -6
- package/package.json +2 -2
|
@@ -941,6 +941,11 @@ function configureGatewayScheduling(modeConfig, configPath = CONFIG_FILE) {
|
|
|
941
941
|
config.channels.defaults.heartbeat.showOk = true;
|
|
942
942
|
}
|
|
943
943
|
|
|
944
|
+
if (!config.agents.defaults || typeof config.agents.defaults !== "object") {
|
|
945
|
+
config.agents.defaults = {};
|
|
946
|
+
}
|
|
947
|
+
config.agents.defaults.heartbeat = { ...defaultHeartbeat };
|
|
948
|
+
|
|
944
949
|
ensureAgentsDefaultsSchemaCompat(config);
|
|
945
950
|
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
946
951
|
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
@@ -1498,6 +1503,7 @@ export class InstallerStepEngine {
|
|
|
1498
1503
|
xAccessTokenCtoSecret: typeof options.xAccessTokenCtoSecret === "string" ? options.xAccessTokenCtoSecret : "",
|
|
1499
1504
|
xAccessTokenIntern: typeof options.xAccessTokenIntern === "string" ? options.xAccessTokenIntern : "",
|
|
1500
1505
|
xAccessTokenInternSecret: typeof options.xAccessTokenInternSecret === "string" ? options.xAccessTokenInternSecret : "",
|
|
1506
|
+
referralCode: typeof options.referralCode === "string" ? options.referralCode.trim() : "",
|
|
1501
1507
|
};
|
|
1502
1508
|
this.hooks = {
|
|
1503
1509
|
onStepEvent: typeof hooks.onStepEvent === "function" ? hooks.onStepEvent : () => {},
|
|
@@ -1783,6 +1789,11 @@ export class InstallerStepEngine {
|
|
|
1783
1789
|
args.push("--gateway-base-url", gatewayBaseUrl);
|
|
1784
1790
|
}
|
|
1785
1791
|
|
|
1792
|
+
const ref = String(this.options.referralCode || "").trim();
|
|
1793
|
+
if (ref) {
|
|
1794
|
+
args.push("--referral-code", ref);
|
|
1795
|
+
}
|
|
1796
|
+
|
|
1786
1797
|
const command = [this.modeConfig.cliName, ...args].join(" ");
|
|
1787
1798
|
const docs =
|
|
1788
1799
|
"https://docs.traderclaw.ai/docs/installation#troubleshooting-session-expired-auth-errors-or-the-agent-logged-out";
|
package/bin/openclaw-trader.mjs
CHANGED
|
@@ -520,15 +520,22 @@ function signChallengeLocally(challengeText, privateKeyBase58) {
|
|
|
520
520
|
return b58Encode(new Uint8Array(sig));
|
|
521
521
|
}
|
|
522
522
|
|
|
523
|
-
async function doSignup(orchestratorUrl, externalUserId) {
|
|
523
|
+
async function doSignup(orchestratorUrl, externalUserId, referralCode = "") {
|
|
524
524
|
printInfo(` Signing up as: ${externalUserId}`);
|
|
525
|
+
const body = { externalUserId };
|
|
526
|
+
const ref = String(referralCode || "").trim();
|
|
527
|
+
if (ref) body.referralCode = ref;
|
|
525
528
|
const res = await httpRequest(`${orchestratorUrl}/api/auth/signup`, {
|
|
526
529
|
method: "POST",
|
|
527
|
-
body
|
|
530
|
+
body,
|
|
528
531
|
});
|
|
529
532
|
|
|
530
533
|
if (!res.ok) {
|
|
531
|
-
|
|
534
|
+
const payload = res.data && typeof res.data === "object" ? res.data : {};
|
|
535
|
+
const apiMsg = typeof payload.message === "string" ? payload.message : JSON.stringify(res.data);
|
|
536
|
+
const err = new Error(`Signup failed (HTTP ${res.status}): ${apiMsg}`);
|
|
537
|
+
if (typeof payload.code === "string") err.code = payload.code;
|
|
538
|
+
throw err;
|
|
532
539
|
}
|
|
533
540
|
|
|
534
541
|
return res.data;
|
|
@@ -700,6 +707,8 @@ async function cmdSetup(args) {
|
|
|
700
707
|
let noEnsureGatewayPersistent = false;
|
|
701
708
|
let signupRecoverySecret = undefined;
|
|
702
709
|
let forwardTelegramRecipientArg = "";
|
|
710
|
+
let referralCodeArg = "";
|
|
711
|
+
let referralInvalidRetries = 0;
|
|
703
712
|
|
|
704
713
|
for (let i = 0; i < args.length; i++) {
|
|
705
714
|
if ((args[i] === "--api-key" || args[i] === "-k") && args[i + 1]) {
|
|
@@ -746,6 +755,9 @@ async function cmdSetup(args) {
|
|
|
746
755
|
) {
|
|
747
756
|
forwardTelegramRecipientArg = args[++i];
|
|
748
757
|
}
|
|
758
|
+
if ((args[i] === "--referral-code" || args[i] === "-r") && args[i + 1]) {
|
|
759
|
+
referralCodeArg = args[++i];
|
|
760
|
+
}
|
|
749
761
|
}
|
|
750
762
|
const runtimeWalletPrivateKey = getRuntimeWalletPrivateKey(walletPrivateKey);
|
|
751
763
|
|
|
@@ -763,6 +775,16 @@ async function cmdSetup(args) {
|
|
|
763
775
|
}
|
|
764
776
|
}
|
|
765
777
|
|
|
778
|
+
if (doSignupFlow && !referralCodeArg) {
|
|
779
|
+
printInfo(
|
|
780
|
+
"\n Optional: enter a referral code for bonus access time (24h extra when valid). Press Enter to skip.\n",
|
|
781
|
+
);
|
|
782
|
+
printInfo(
|
|
783
|
+
" Benefits: extra trial time now; referring others later earns +8h per user who completes at least one trade with the agent.\n",
|
|
784
|
+
);
|
|
785
|
+
referralCodeArg = await prompt("Referral code (optional)", "");
|
|
786
|
+
}
|
|
787
|
+
|
|
766
788
|
if (doSignupFlow) {
|
|
767
789
|
print("\n Signing up for a new account...\n");
|
|
768
790
|
if (!externalUserId) {
|
|
@@ -771,7 +793,7 @@ async function cmdSetup(args) {
|
|
|
771
793
|
|
|
772
794
|
for (let signupAttempt = 0; ; signupAttempt++) {
|
|
773
795
|
try {
|
|
774
|
-
const signupResult = await doSignup(orchestratorUrl, externalUserId);
|
|
796
|
+
const signupResult = await doSignup(orchestratorUrl, externalUserId, referralCodeArg);
|
|
775
797
|
apiKey = signupResult.apiKey;
|
|
776
798
|
if (signupResult.recoverySecret) {
|
|
777
799
|
signupRecoverySecret = signupResult.recoverySecret;
|
|
@@ -783,6 +805,22 @@ async function cmdSetup(args) {
|
|
|
783
805
|
break;
|
|
784
806
|
} catch (err) {
|
|
785
807
|
const msg = err.message || String(err);
|
|
808
|
+
const apiCode = err.code;
|
|
809
|
+
const referralRejected =
|
|
810
|
+
apiCode === "REFERRAL_CODE_INVALID" ||
|
|
811
|
+
msg.includes("REFERRAL_CODE_INVALID") ||
|
|
812
|
+
msg.includes("Unknown referral code");
|
|
813
|
+
if (referralRejected) {
|
|
814
|
+
referralInvalidRetries += 1;
|
|
815
|
+
if (referralInvalidRetries > 30) {
|
|
816
|
+
printError("Too many invalid referral attempts. Aborting.");
|
|
817
|
+
process.exit(1);
|
|
818
|
+
}
|
|
819
|
+
printWarn(" That referral code was not accepted (unknown or invalid).");
|
|
820
|
+
printInfo(" Leave it blank or enter a different code, then try again.");
|
|
821
|
+
referralCodeArg = await prompt("Referral code (optional, leave empty to skip)", "");
|
|
822
|
+
continue;
|
|
823
|
+
}
|
|
786
824
|
if (msg.includes("SIGNUP_ALREADY_COMPLETED") || msg.includes("409")) {
|
|
787
825
|
printWarn(` User "${externalUserId}" is already registered.`);
|
|
788
826
|
if (signupAttempt >= 2) {
|
|
@@ -2176,6 +2214,7 @@ function wizardHtml(defaults) {
|
|
|
2176
2214
|
.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
2215
|
.muted a { color:#9fd3ff; }
|
|
2178
2216
|
.muted a:hover { color:#c5e5ff; }
|
|
2217
|
+
.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
2218
|
@keyframes spin { to { transform:rotate(360deg); } }
|
|
2180
2219
|
</style>
|
|
2181
2220
|
</head>
|
|
@@ -2253,6 +2292,13 @@ function wizardHtml(defaults) {
|
|
|
2253
2292
|
<p class="muted">Already have a TraderClaw account? Paste your API key here. New users: leave empty.</p>
|
|
2254
2293
|
</div>
|
|
2255
2294
|
</div>
|
|
2295
|
+
<div style="margin-top:12px;">
|
|
2296
|
+
<label style="display:flex;align-items:center;gap:8px;">Referral code (optional)
|
|
2297
|
+
<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>
|
|
2298
|
+
</label>
|
|
2299
|
+
<input id="referralCode" type="text" maxlength="16" autocomplete="off" placeholder="e.g. ABCD1234" />
|
|
2300
|
+
<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>
|
|
2301
|
+
</div>
|
|
2256
2302
|
<button id="start" disabled>Start Installation</button>
|
|
2257
2303
|
</div>
|
|
2258
2304
|
<div class="card" id="statusCard">
|
|
@@ -2361,6 +2407,7 @@ function wizardHtml(defaults) {
|
|
|
2361
2407
|
let llmLoadStartedAt = 0;
|
|
2362
2408
|
let announcedTailscaleUrl = "";
|
|
2363
2409
|
let announcedFunnelAdminUrl = "";
|
|
2410
|
+
let lastReferralFailFingerprint = "";
|
|
2364
2411
|
let pollTimer = null;
|
|
2365
2412
|
let pollIntervalMs = 1200;
|
|
2366
2413
|
let installLocked = false;
|
|
@@ -2555,6 +2602,7 @@ function wizardHtml(defaults) {
|
|
|
2555
2602
|
llmCredential: llmCredentialEl.value.trim(),
|
|
2556
2603
|
apiKey: document.getElementById("apiKey").value.trim(),
|
|
2557
2604
|
telegramToken: document.getElementById("telegramToken").value.trim(),
|
|
2605
|
+
referralCode: document.getElementById("referralCode").value.trim(),
|
|
2558
2606
|
xConsumerKey: xConsumerKeyEl.value.trim(),
|
|
2559
2607
|
xConsumerSecret: xConsumerSecretEl.value.trim(),
|
|
2560
2608
|
xAccessTokenMain: xAccessTokenMainEl.value.trim(),
|
|
@@ -2716,9 +2764,30 @@ function wizardHtml(defaults) {
|
|
|
2716
2764
|
}
|
|
2717
2765
|
|
|
2718
2766
|
const errors = data.errors || [];
|
|
2719
|
-
|
|
2767
|
+
let manualText = errors.length > 0
|
|
2720
2768
|
? errors.map((e) => "Step " + (e.stepId || "unknown") + ":\\n" + (e.error || "")).join("\\n\\n")
|
|
2721
2769
|
: "";
|
|
2770
|
+
const combinedErr = errors.map((e) => e.error || "").join("\\n");
|
|
2771
|
+
if (
|
|
2772
|
+
data.status === "failed"
|
|
2773
|
+
&& /REFERRAL_CODE_INVALID|Unknown referral code/i.test(combinedErr)
|
|
2774
|
+
) {
|
|
2775
|
+
manualText +=
|
|
2776
|
+
(manualText ? "\\n\\n" : "") +
|
|
2777
|
+
"Referral code was rejected. Clear or fix the referral field above, then click Start Installation again.";
|
|
2778
|
+
const fp = combinedErr.slice(0, 240);
|
|
2779
|
+
if (fp && fp !== lastReferralFailFingerprint) {
|
|
2780
|
+
lastReferralFailFingerprint = fp;
|
|
2781
|
+
try {
|
|
2782
|
+
window.alert(
|
|
2783
|
+
"Referral code was not accepted. Update or clear the referral field, then click Start Installation again.",
|
|
2784
|
+
);
|
|
2785
|
+
} catch {
|
|
2786
|
+
/* ignore */
|
|
2787
|
+
}
|
|
2788
|
+
}
|
|
2789
|
+
}
|
|
2790
|
+
manualEl.textContent = manualText;
|
|
2722
2791
|
stepsEl.innerHTML = "";
|
|
2723
2792
|
steps.forEach((row) => {
|
|
2724
2793
|
const tr = document.createElement("tr");
|
|
@@ -2938,6 +3007,7 @@ async function cmdInstall(args) {
|
|
|
2938
3007
|
enableTelegram: true,
|
|
2939
3008
|
telegramToken: body.telegramToken || defaults.telegramToken,
|
|
2940
3009
|
autoInstallDeps: true,
|
|
3010
|
+
referralCode: typeof body.referralCode === "string" ? body.referralCode.trim() : "",
|
|
2941
3011
|
xConsumerKey: body.xConsumerKey ?? defaults.xConsumerKey,
|
|
2942
3012
|
xConsumerSecret: body.xConsumerSecret ?? defaults.xConsumerSecret,
|
|
2943
3013
|
xAccessTokenMain: body.xAccessTokenMain ?? defaults.xAccessTokenMain,
|
|
@@ -2973,6 +3043,7 @@ async function cmdInstall(args) {
|
|
|
2973
3043
|
enableTelegram: true,
|
|
2974
3044
|
telegramToken: body.telegramToken || defaults.telegramToken,
|
|
2975
3045
|
autoInstallDeps: true,
|
|
3046
|
+
referralCode: wizardOpts.referralCode,
|
|
2976
3047
|
xConsumerKey: wizardOpts.xConsumerKey,
|
|
2977
3048
|
xConsumerSecret: wizardOpts.xConsumerSecret,
|
|
2978
3049
|
xAccessTokenMain: wizardOpts.xAccessTokenMain,
|
|
@@ -3227,7 +3298,14 @@ async function cmdTestSession(args) {
|
|
|
3227
3298
|
try {
|
|
3228
3299
|
if (currentRefreshToken && currentAccessToken) {
|
|
3229
3300
|
mkdirSync(dataDir, { recursive: true });
|
|
3301
|
+
let existingSidecar = {};
|
|
3302
|
+
try {
|
|
3303
|
+
if (existsSync(sessionTokensPath)) {
|
|
3304
|
+
existingSidecar = JSON.parse(readFileSync(sessionTokensPath, "utf-8")) || {};
|
|
3305
|
+
}
|
|
3306
|
+
} catch { /* ignore */ }
|
|
3230
3307
|
const payload = {
|
|
3308
|
+
...existingSidecar,
|
|
3231
3309
|
refreshToken: currentRefreshToken,
|
|
3232
3310
|
accessToken: currentAccessToken,
|
|
3233
3311
|
accessTokenExpiresAt: Date.now() + 900_000,
|
|
@@ -3304,6 +3382,7 @@ Setup options:
|
|
|
3304
3382
|
--gateway-base-url, -g Gateway public HTTPS URL for orchestrator callbacks
|
|
3305
3383
|
--gateway-token, -t Gateway bearer token (defaults to API key)
|
|
3306
3384
|
--telegram-recipient Telegram @username or chat id (aliases: --forward-telegram-chat-id, --telegram-chat-id)
|
|
3385
|
+
--referral-code, -r Optional referral code for new signups (extra trial time when valid)
|
|
3307
3386
|
--skip-gateway-registration Skip gateway URL registration with orchestrator
|
|
3308
3387
|
--show-api-key Extra hint after signup (full key is always shown once; confirm with API_KEY_STORED)
|
|
3309
3388
|
--show-wallet-private-key Reveal full wallet private key in setup output
|
|
@@ -3333,7 +3412,7 @@ Examples:
|
|
|
3333
3412
|
traderclaw install --wizard
|
|
3334
3413
|
traderclaw install --wizard --lane quick-local
|
|
3335
3414
|
traderclaw gateway ensure-persistent
|
|
3336
|
-
traderclaw setup --signup --user-id my_agent_001
|
|
3415
|
+
traderclaw setup --signup --user-id my_agent_001 --referral-code ABCD1234
|
|
3337
3416
|
traderclaw setup --api-key oc_xxx --url https://api.traderclaw.ai
|
|
3338
3417
|
traderclaw setup --gateway-base-url https://gateway.myhost.ts.net
|
|
3339
3418
|
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.63",
|
|
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.63"
|
|
21
21
|
},
|
|
22
22
|
"keywords": [
|
|
23
23
|
"traderclaw",
|