@tokenbuddy/tokenbuddy 1.0.6 â 1.0.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/dist/src/buyer-store.d.ts +28 -1
- package/dist/src/buyer-store.d.ts.map +1 -1
- package/dist/src/buyer-store.js +71 -16
- package/dist/src/buyer-store.js.map +1 -1
- package/dist/src/cli.d.ts +17 -0
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +201 -32
- package/dist/src/cli.js.map +1 -1
- package/dist/src/daemon.d.ts +5 -0
- package/dist/src/daemon.d.ts.map +1 -1
- package/dist/src/daemon.js +279 -72
- package/dist/src/daemon.js.map +1 -1
- package/dist/src/doctor-clawtip-wallet.d.ts +14 -0
- package/dist/src/doctor-clawtip-wallet.d.ts.map +1 -0
- package/dist/src/doctor-clawtip-wallet.js +54 -0
- package/dist/src/doctor-clawtip-wallet.js.map +1 -0
- package/dist/src/doctor-diagnostics.d.ts +2 -0
- package/dist/src/doctor-diagnostics.d.ts.map +1 -1
- package/dist/src/doctor-diagnostics.js +5 -0
- package/dist/src/doctor-diagnostics.js.map +1 -1
- package/dist/src/init-clawtip-activation.d.ts +48 -0
- package/dist/src/init-clawtip-activation.d.ts.map +1 -0
- package/dist/src/init-clawtip-activation.js +395 -0
- package/dist/src/init-clawtip-activation.js.map +1 -0
- package/dist/src/init-payment-options.d.ts +23 -1
- package/dist/src/init-payment-options.d.ts.map +1 -1
- package/dist/src/init-payment-options.js +97 -22
- package/dist/src/init-payment-options.js.map +1 -1
- package/dist/src/terminal-image.d.ts +22 -0
- package/dist/src/terminal-image.d.ts.map +1 -0
- package/dist/src/terminal-image.js +135 -0
- package/dist/src/terminal-image.js.map +1 -0
- package/package.json +1 -1
- package/src/buyer-store.ts +140 -17
- package/src/cli.ts +251 -33
- package/src/daemon.ts +308 -53
- package/src/doctor-clawtip-wallet.ts +70 -0
- package/src/doctor-diagnostics.ts +11 -0
- package/src/init-clawtip-activation.ts +487 -0
- package/src/init-payment-options.ts +140 -22
- package/src/terminal-image.ts +187 -0
- package/tests/e2e.test.ts +79 -5
- package/tests/tokenbuddy.test.ts +745 -19
package/src/cli.ts
CHANGED
|
@@ -36,15 +36,24 @@ import {
|
|
|
36
36
|
renderDoctorDiagnosticsProgressively,
|
|
37
37
|
} from "./doctor-diagnostics.js";
|
|
38
38
|
import {
|
|
39
|
-
buildInitTerminalOptions,
|
|
40
39
|
buildInitSuccessMessage,
|
|
41
|
-
|
|
40
|
+
buildInitTerminalSelectionState,
|
|
41
|
+
buildInstalledTerminalMessage,
|
|
42
42
|
INIT_PAYMENT_OPTIONS,
|
|
43
|
+
inspectClawtipWalletReadiness,
|
|
44
|
+
inspectOpenClawWalletConfig,
|
|
43
45
|
noteInitComingSoonPayments,
|
|
44
46
|
OTHER_TERMINAL_OPTION,
|
|
45
47
|
type InitPaymentMethod,
|
|
46
48
|
validateInitTerminalSelection,
|
|
47
49
|
} from "./init-payment-options.js";
|
|
50
|
+
import {
|
|
51
|
+
checkOpenClawRuntime,
|
|
52
|
+
readClawtipPayCredential,
|
|
53
|
+
startClawtipWalletBootstrap,
|
|
54
|
+
waitForClawtipActivationConfirmation,
|
|
55
|
+
} from "./init-clawtip-activation.js";
|
|
56
|
+
import { displayTerminalImage } from "./terminal-image.js";
|
|
48
57
|
|
|
49
58
|
// @ts-ignore
|
|
50
59
|
import qrcode from "qrcode-terminal";
|
|
@@ -162,6 +171,20 @@ async function probeDaemonStatus(controlPort: number): Promise<DaemonProbeResult
|
|
|
162
171
|
}
|
|
163
172
|
}
|
|
164
173
|
|
|
174
|
+
interface NormalizedClawtipPaymentPayload {
|
|
175
|
+
orderNo: string;
|
|
176
|
+
amountFen?: number;
|
|
177
|
+
payTo?: string;
|
|
178
|
+
encryptedData?: string;
|
|
179
|
+
indicator: string;
|
|
180
|
+
slug?: string;
|
|
181
|
+
skillId?: string;
|
|
182
|
+
description?: string;
|
|
183
|
+
resourceUrl: string;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const CLAWTIP_BOOTSTRAP_PLACEHOLDER_PAY_TO = "bootstrap-pay-to";
|
|
187
|
+
|
|
165
188
|
async function waitForDaemonStatus(controlPort: number, timeoutMs: number): Promise<DaemonProbeResult> {
|
|
166
189
|
const deadline = Date.now() + timeoutMs;
|
|
167
190
|
let latest: DaemonProbeResult = { running: false, error: "not checked" };
|
|
@@ -335,7 +358,7 @@ function printPaymentList(payments: PaymentConfig[], asJson: boolean): void {
|
|
|
335
358
|
console.log(table.toString());
|
|
336
359
|
}
|
|
337
360
|
|
|
338
|
-
async function fetchClawtipBootstrap(bootstrapUrl: string): Promise<ClawtipBootstrapResponse> {
|
|
361
|
+
export async function fetchClawtipBootstrap(bootstrapUrl: string): Promise<ClawtipBootstrapResponse> {
|
|
339
362
|
const response = await fetch(`${bootstrapUrl.replace(/\/+$/, "")}/payments/clawtip/bootstrap`, {
|
|
340
363
|
method: "POST",
|
|
341
364
|
headers: { "Content-Type": "application/json" },
|
|
@@ -348,9 +371,35 @@ async function fetchClawtipBootstrap(bootstrapUrl: string): Promise<ClawtipBoots
|
|
|
348
371
|
if (!body.payment?.orderNo || !body.payment.indicator || !body.payment.resourceUrl) {
|
|
349
372
|
throw new Error("ClawTip bootstrap response missing payment order fields");
|
|
350
373
|
}
|
|
374
|
+
if ((body.payment.payTo || "").trim() === CLAWTIP_BOOTSTRAP_PLACEHOLDER_PAY_TO) {
|
|
375
|
+
throw new Error(
|
|
376
|
+
[
|
|
377
|
+
`ClawTip bootstrap service is misconfigured: payTo is still the placeholder \`${CLAWTIP_BOOTSTRAP_PLACEHOLDER_PAY_TO}\`.`,
|
|
378
|
+
`Bootstrap URL: ${bootstrapUrl}`,
|
|
379
|
+
"Configure the bootstrap service with the real ClawTip merchant pay_to before retrying `tb init`.",
|
|
380
|
+
].join(" ")
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
body.payment.resourceUrl = normalizeClawtipBootstrapResourceUrl(bootstrapUrl, body.payment.resourceUrl);
|
|
351
384
|
return body;
|
|
352
385
|
}
|
|
353
386
|
|
|
387
|
+
export function normalizeClawtipBootstrapResourceUrl(bootstrapUrl: string, resourceUrl: string): string {
|
|
388
|
+
try {
|
|
389
|
+
const bootstrap = new URL(bootstrapUrl);
|
|
390
|
+
const resource = new URL(resourceUrl);
|
|
391
|
+
if (resource.origin === bootstrap.origin && resource.pathname === "/registry/sellers") {
|
|
392
|
+
resource.pathname = bootstrap.pathname.replace(/\/+$/, "") || "/";
|
|
393
|
+
resource.search = "";
|
|
394
|
+
resource.hash = "";
|
|
395
|
+
return resource.toString().replace(/\/$/, "");
|
|
396
|
+
}
|
|
397
|
+
} catch {
|
|
398
|
+
// Leave the server-provided value unchanged when URL parsing fails.
|
|
399
|
+
}
|
|
400
|
+
return resourceUrl;
|
|
401
|
+
}
|
|
402
|
+
|
|
354
403
|
function readProof(options: { proofFile?: string; requireProof?: boolean }): string | undefined {
|
|
355
404
|
const proofFile = options.proofFile || process.env.TOKENBUDDY_CLAWTIP_PROOF_FILE;
|
|
356
405
|
if (!proofFile) {
|
|
@@ -913,15 +962,21 @@ export function buildCli(): Command {
|
|
|
913
962
|
const spinner = p.spinner();
|
|
914
963
|
spinner.start("Scanning local system for programming terminals...");
|
|
915
964
|
const candidates = detectProviders();
|
|
916
|
-
const
|
|
965
|
+
const terminalSelection = buildInitTerminalSelectionState(candidates);
|
|
917
966
|
spinner.stop("Scan completed.");
|
|
918
967
|
|
|
919
|
-
|
|
968
|
+
const installedTerminalMessage = buildInstalledTerminalMessage(terminalSelection.installed);
|
|
969
|
+
if (installedTerminalMessage) {
|
|
970
|
+
p.note(installedTerminalMessage, "Already Configured");
|
|
971
|
+
setupSummaryLines.push(`${terminalSelection.installed.length} terminal${terminalSelection.installed.length === 1 ? "" : "s"} already configured.`);
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
if (terminalSelection.options.length === 1 && terminalSelection.options[0].value === OTHER_TERMINAL_OPTION.value) {
|
|
920
975
|
p.note("No active programming terminals detected. Install one of Codex, Claude Code, Claude Desktop, OpenCode, OpenClaw or Hermes first.");
|
|
921
976
|
} else {
|
|
922
977
|
const selected = await p.multiselect({
|
|
923
978
|
message: "Select programming terminals to route via TokenBuddy (use Space to select, Enter to confirm):",
|
|
924
|
-
options:
|
|
979
|
+
options: terminalSelection.options,
|
|
925
980
|
required: false
|
|
926
981
|
}) as string[];
|
|
927
982
|
|
|
@@ -1008,7 +1063,9 @@ export function buildCli(): Command {
|
|
|
1008
1063
|
if (payMethod === "clawtip") {
|
|
1009
1064
|
const store = openBuyerStore();
|
|
1010
1065
|
try {
|
|
1011
|
-
|
|
1066
|
+
let walletConfig = inspectOpenClawWalletConfig();
|
|
1067
|
+
const clawtipReadiness = inspectClawtipWalletReadiness(store.getPayment("clawtip"), walletConfig);
|
|
1068
|
+
const existingClawtip = clawtipReadiness.reusableBinding;
|
|
1012
1069
|
if (existingClawtip) {
|
|
1013
1070
|
store.savePayment({
|
|
1014
1071
|
method: "clawtip",
|
|
@@ -1033,30 +1090,159 @@ export function buildCli(): Command {
|
|
|
1033
1090
|
);
|
|
1034
1091
|
setupSummaryLines.push("ClawTip wallet already bound locally; activation skipped.");
|
|
1035
1092
|
} else {
|
|
1093
|
+
if (clawtipReadiness.status === "metadata_missing_wallet") {
|
|
1094
|
+
p.note(
|
|
1095
|
+
[
|
|
1096
|
+
clawtipReadiness.message,
|
|
1097
|
+
`Expected: ${walletConfig.expectedPath}`,
|
|
1098
|
+
walletConfig.alternatePaths.length > 0
|
|
1099
|
+
? `Alternates: ${walletConfig.alternatePaths.join(", ")}`
|
|
1100
|
+
: "Alternates: -"
|
|
1101
|
+
].join("\n"),
|
|
1102
|
+
"ClawTip"
|
|
1103
|
+
);
|
|
1104
|
+
setupSummaryLines.push("Saved ClawTip metadata found, but local wallet config is missing; activation restarted.");
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
const walletReadyBeforePay = walletConfig.exists;
|
|
1108
|
+
let openClawVersion: string | undefined;
|
|
1109
|
+
if (!walletReadyBeforePay) {
|
|
1110
|
+
spinner.start("Checking OpenClaw CLI before ClawTip wallet bootstrap...");
|
|
1111
|
+
openClawVersion = await checkOpenClawRuntime();
|
|
1112
|
+
spinner.stop("OpenClaw CLI detected.");
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1036
1115
|
spinner.start("Requesting payment activation payload from public bootstrap registry...");
|
|
1037
1116
|
const bootstrapUrl = process.env.TOKENBUDDY_BOOTSTRAP_URL || "https://tb-wallet-bootstrap.fly.dev";
|
|
1038
|
-
const
|
|
1039
|
-
method: "POST",
|
|
1040
|
-
headers: { "Content-Type": "application/json" },
|
|
1041
|
-
body: JSON.stringify({ clientTag: "cli-init" })
|
|
1042
|
-
});
|
|
1043
|
-
const data: any = await res.json();
|
|
1117
|
+
const bootstrap = await fetchClawtipBootstrap(bootstrapUrl);
|
|
1044
1118
|
spinner.stop("Bootstrap payload received.");
|
|
1045
1119
|
|
|
1046
|
-
|
|
1120
|
+
if (!bootstrap.payment?.orderNo || !bootstrap.payment?.indicator) {
|
|
1121
|
+
throw new Error("ClawTip bootstrap response missing orderNo or indicator.");
|
|
1122
|
+
}
|
|
1047
1123
|
|
|
1048
|
-
|
|
1124
|
+
const activationPayment = {
|
|
1125
|
+
orderNo: bootstrap.payment.orderNo,
|
|
1126
|
+
amountFen: bootstrap.payment.amountFen ?? bootstrap.activationFeeFen ?? 1,
|
|
1127
|
+
payTo: bootstrap.payment.payTo,
|
|
1128
|
+
encryptedData: bootstrap.payment.encryptedData,
|
|
1129
|
+
indicator: bootstrap.payment.indicator,
|
|
1130
|
+
slug: bootstrap.payment.slug,
|
|
1131
|
+
skillId: bootstrap.payment.skillId,
|
|
1132
|
+
description: bootstrap.payment.description,
|
|
1133
|
+
resourceUrl: bootstrap.payment.resourceUrl,
|
|
1134
|
+
};
|
|
1135
|
+
|
|
1136
|
+
spinner.start("Starting the ClawTip payment activation flow...");
|
|
1137
|
+
let activation = await startClawtipWalletBootstrap(activationPayment);
|
|
1138
|
+
spinner.stop("ClawTip payment activation finished.");
|
|
1139
|
+
|
|
1140
|
+
let payCredential = activation.payCredential;
|
|
1141
|
+
for (
|
|
1142
|
+
let authAttempt = 1;
|
|
1143
|
+
(walletReadyBeforePay ? !payCredential : !walletConfig.exists)
|
|
1144
|
+
&& activation.parsedOutput.requiresWalletAuth
|
|
1145
|
+
&& authAttempt <= 3;
|
|
1146
|
+
authAttempt += 1
|
|
1147
|
+
) {
|
|
1148
|
+
let qrDisplayMessage: string | undefined;
|
|
1149
|
+
let manualOpenCommand: string | undefined;
|
|
1150
|
+
if (activation.parsedOutput.mediaPath) {
|
|
1151
|
+
const qrDisplay = await displayTerminalImage(activation.parsedOutput.mediaPath);
|
|
1152
|
+
qrDisplayMessage = qrDisplay.message;
|
|
1153
|
+
manualOpenCommand = qrDisplay.fallbackCommand;
|
|
1154
|
+
}
|
|
1155
|
+
if (!activation.parsedOutput.mediaPath && !activation.parsedOutput.authUrl) {
|
|
1156
|
+
throw new Error(
|
|
1157
|
+
`ClawTip pay requested authorization but did not return QR media or authUrl. Order file: ${activation.orderFile}`
|
|
1158
|
+
);
|
|
1159
|
+
}
|
|
1160
|
+
p.note(
|
|
1161
|
+
[
|
|
1162
|
+
activation.parsedOutput.mediaPath
|
|
1163
|
+
? `Open or scan this ClawTip wallet QR image with the JD app: ${activation.parsedOutput.mediaPath}`
|
|
1164
|
+
: undefined,
|
|
1165
|
+
activation.parsedOutput.authUrl
|
|
1166
|
+
? `Open or scan this ClawTip wallet auth URL with the JD app: ${activation.parsedOutput.authUrl}`
|
|
1167
|
+
: undefined,
|
|
1168
|
+
qrDisplayMessage,
|
|
1169
|
+
manualOpenCommand ? `Manual open command: ${manualOpenCommand}` : undefined,
|
|
1170
|
+
activation.parsedOutput.clawtipId ? `clawtipId: ${activation.parsedOutput.clawtipId}` : undefined,
|
|
1171
|
+
activation.parsedOutput.clawtipId
|
|
1172
|
+
? "After scanning, ClawTip CLI will register the local agent wallet."
|
|
1173
|
+
: "After scanning, TokenBuddy will retry ClawTip payment activation.",
|
|
1174
|
+
`Expected wallet config: ${walletConfig.expectedPath}`,
|
|
1175
|
+
openClawVersion ? `OpenClaw: ${openClawVersion}` : undefined,
|
|
1176
|
+
].filter(Boolean).join("\n"),
|
|
1177
|
+
activation.parsedOutput.clawtipId ? "ClawTip Wallet QR" : "ClawTip Authorization QR"
|
|
1178
|
+
);
|
|
1179
|
+
|
|
1180
|
+
if (activation.parsedOutput.clawtipId && !walletReadyBeforePay) {
|
|
1181
|
+
spinner.start("Waiting for ClawTip wallet registration. Press Ctrl+C to cancel.");
|
|
1182
|
+
const walletRegistered = await waitForClawtipActivationConfirmation({
|
|
1183
|
+
clawtipId: activation.parsedOutput.clawtipId,
|
|
1184
|
+
});
|
|
1185
|
+
spinner.stop(walletRegistered
|
|
1186
|
+
? "Detected local OpenClaw ClawTip wallet config."
|
|
1187
|
+
: "ClawTip wallet registration cancelled.");
|
|
1188
|
+
if (!walletRegistered) {
|
|
1189
|
+
setupSummaryLines.push("ClawTip wallet registration was cancelled before local wallet config was saved.");
|
|
1190
|
+
process.exitCode = 1;
|
|
1191
|
+
return;
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
walletConfig = inspectOpenClawWalletConfig();
|
|
1195
|
+
if (!walletConfig.exists) {
|
|
1196
|
+
throw new Error(`ClawTip wallet registration finished but wallet config is still missing: ${walletConfig.expectedPath}`);
|
|
1197
|
+
}
|
|
1198
|
+
setupSummaryLines.push("ClawTip wallet registered locally.");
|
|
1199
|
+
} else {
|
|
1200
|
+
const authorized = await p.confirm({
|
|
1201
|
+
message: "Scan or authorize this ClawTip QR in the JD app, then press Enter to retry payment activation.",
|
|
1202
|
+
initialValue: true,
|
|
1203
|
+
});
|
|
1204
|
+
if (authorized !== true) {
|
|
1205
|
+
setupSummaryLines.push("ClawTip authorization was cancelled before payment activation completed.");
|
|
1206
|
+
process.exitCode = 1;
|
|
1207
|
+
return;
|
|
1208
|
+
}
|
|
1209
|
+
walletConfig = inspectOpenClawWalletConfig();
|
|
1210
|
+
}
|
|
1049
1211
|
|
|
1050
|
-
|
|
1051
|
-
|
|
1212
|
+
payCredential = readClawtipPayCredential(activation.orderFile);
|
|
1213
|
+
if (!payCredential) {
|
|
1214
|
+
spinner.start(`Retrying ClawTip payment activation after authorization (${authAttempt}/3)...`);
|
|
1215
|
+
activation = await startClawtipWalletBootstrap(activationPayment);
|
|
1216
|
+
spinner.stop("ClawTip payment activation retry finished.");
|
|
1217
|
+
payCredential = activation.payCredential;
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1052
1220
|
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1221
|
+
const refreshedWalletConfig = inspectOpenClawWalletConfig();
|
|
1222
|
+
if (!walletReadyBeforePay && !refreshedWalletConfig.exists) {
|
|
1223
|
+
const paymentQrMessage = activation.parsedOutput.mediaPath
|
|
1224
|
+
? ` ClawTip pay returned QR media: ${activation.parsedOutput.mediaPath}`
|
|
1225
|
+
: " ClawTip pay did not return QR media.";
|
|
1226
|
+
throw new Error(
|
|
1227
|
+
[
|
|
1228
|
+
`ClawTip wallet config is still missing after payment activation: ${refreshedWalletConfig.expectedPath}.`,
|
|
1229
|
+
`Order file: ${activation.orderFile}.`,
|
|
1230
|
+
paymentQrMessage.trim(),
|
|
1231
|
+
].join(" ")
|
|
1232
|
+
);
|
|
1058
1233
|
}
|
|
1059
|
-
|
|
1234
|
+
const completedByWalletConfig = !payCredential && !walletReadyBeforePay && refreshedWalletConfig.exists;
|
|
1235
|
+
if (!payCredential && !completedByWalletConfig) {
|
|
1236
|
+
const paymentQrMessage = activation.parsedOutput.mediaPath
|
|
1237
|
+
? ` ClawTip pay returned QR media: ${activation.parsedOutput.mediaPath}`
|
|
1238
|
+
: "";
|
|
1239
|
+
throw new Error(
|
|
1240
|
+
`ClawTip pay did not write payCredential to the order file. Order file: ${activation.orderFile}.${paymentQrMessage}`
|
|
1241
|
+
);
|
|
1242
|
+
}
|
|
1243
|
+
const activationCompletedBy = payCredential
|
|
1244
|
+
? (refreshedWalletConfig.exists ? "payCredential+wallet-config" : "payCredential")
|
|
1245
|
+
: "wallet-config";
|
|
1060
1246
|
|
|
1061
1247
|
store.savePayment({
|
|
1062
1248
|
method: "clawtip",
|
|
@@ -1064,21 +1250,53 @@ export function buildCli(): Command {
|
|
|
1064
1250
|
isDefault: true,
|
|
1065
1251
|
config: {
|
|
1066
1252
|
bootstrapUrl,
|
|
1067
|
-
orderNo:
|
|
1068
|
-
amountFen:
|
|
1069
|
-
indicator:
|
|
1070
|
-
slug:
|
|
1071
|
-
skillId:
|
|
1072
|
-
description:
|
|
1073
|
-
resourceUrl:
|
|
1074
|
-
proofRequired: false
|
|
1253
|
+
orderNo: bootstrap.payment?.orderNo,
|
|
1254
|
+
amountFen: bootstrap.payment?.amountFen ?? bootstrap.activationFeeFen,
|
|
1255
|
+
indicator: bootstrap.payment?.indicator,
|
|
1256
|
+
slug: bootstrap.payment?.slug,
|
|
1257
|
+
skillId: bootstrap.payment?.skillId,
|
|
1258
|
+
description: bootstrap.payment?.description,
|
|
1259
|
+
resourceUrl: bootstrap.payment?.resourceUrl,
|
|
1260
|
+
proofRequired: false,
|
|
1261
|
+
activationOrderFile: activation.orderFile,
|
|
1262
|
+
walletConfigPath: refreshedWalletConfig.expectedPath,
|
|
1263
|
+
walletConfigPresent: refreshedWalletConfig.exists,
|
|
1264
|
+
payCredentialWritten: Boolean(payCredential),
|
|
1265
|
+
activationCompletedBy
|
|
1075
1266
|
}
|
|
1076
1267
|
});
|
|
1077
1268
|
logger.info("payment.channel.added", "clawtip payment channel added during init", {
|
|
1078
1269
|
method: "clawtip",
|
|
1079
|
-
orderNo:
|
|
1270
|
+
orderNo: bootstrap.payment?.orderNo,
|
|
1271
|
+
payCredentialWritten: Boolean(payCredential),
|
|
1272
|
+
activationCompletedBy
|
|
1080
1273
|
});
|
|
1081
|
-
|
|
1274
|
+
if (refreshedWalletConfig.exists) {
|
|
1275
|
+
if (!payCredential) {
|
|
1276
|
+
p.note(
|
|
1277
|
+
[
|
|
1278
|
+
"OpenClaw saved the local ClawTip wallet config, but the ClawTip order file did not contain payCredential.",
|
|
1279
|
+
`Order file: ${activation.orderFile}`,
|
|
1280
|
+
"TokenBuddy saved the wallet binding metadata and will rely on the local wallet for future ClawTip purchases."
|
|
1281
|
+
].join("\n"),
|
|
1282
|
+
"ClawTip"
|
|
1283
|
+
);
|
|
1284
|
+
}
|
|
1285
|
+
setupSummaryLines.push("ClawTip wallet activated and set as the default payment method.");
|
|
1286
|
+
} else {
|
|
1287
|
+
p.note(
|
|
1288
|
+
[
|
|
1289
|
+
"ClawTip payment metadata was saved, but the local OpenClaw wallet config is still missing.",
|
|
1290
|
+
`Expected: ${refreshedWalletConfig.expectedPath}`,
|
|
1291
|
+
refreshedWalletConfig.alternatePaths.length > 0
|
|
1292
|
+
? `Nearby files: ${refreshedWalletConfig.alternatePaths.join(", ")}`
|
|
1293
|
+
: "Nearby files: -",
|
|
1294
|
+
"Bind or restore the local wallet before using ClawTip-backed purchases."
|
|
1295
|
+
].join("\n"),
|
|
1296
|
+
"ClawTip Wallet Required"
|
|
1297
|
+
);
|
|
1298
|
+
setupSummaryLines.push("ClawTip payment metadata saved; local wallet config still needs binding before use.");
|
|
1299
|
+
}
|
|
1082
1300
|
}
|
|
1083
1301
|
} catch (err: any) {
|
|
1084
1302
|
spinner.stop(`Failed to finish ClawTip setup: ${err.message}`);
|