@bankr/cli 0.3.12 → 0.3.23

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.
Files changed (41) hide show
  1. package/README.md +28 -10
  2. package/dist/cli.js +31 -8
  3. package/dist/commands/balances.js +2 -1
  4. package/dist/commands/cancel.js +2 -1
  5. package/dist/commands/club.js +4 -3
  6. package/dist/commands/fees.js +83 -45
  7. package/dist/commands/files.js +14 -13
  8. package/dist/commands/launch.d.ts +5 -0
  9. package/dist/commands/launch.js +76 -7
  10. package/dist/commands/llm.d.ts +2 -0
  11. package/dist/commands/llm.js +264 -44
  12. package/dist/commands/login.d.ts +14 -0
  13. package/dist/commands/login.js +41 -30
  14. package/dist/commands/portfolio.js +3 -2
  15. package/dist/commands/profile.js +6 -5
  16. package/dist/commands/prompt.js +19 -6
  17. package/dist/commands/sign.js +2 -1
  18. package/dist/commands/sounds.js +4 -3
  19. package/dist/commands/status.js +3 -2
  20. package/dist/commands/submit.js +3 -2
  21. package/dist/commands/swap.js +9 -7
  22. package/dist/commands/tokens.js +3 -2
  23. package/dist/commands/transfer.js +8 -6
  24. package/dist/commands/update.js +2 -1
  25. package/dist/commands/webhooks.js +15 -10
  26. package/dist/commands/whoami.js +3 -2
  27. package/dist/commands/x402.d.ts +3 -0
  28. package/dist/commands/x402.js +75 -30
  29. package/dist/lib/api.d.ts +18 -1
  30. package/dist/lib/api.js +32 -41
  31. package/dist/lib/errors.d.ts +7 -0
  32. package/dist/lib/errors.js +9 -0
  33. package/dist/lib/explorer.d.ts +7 -0
  34. package/dist/lib/explorer.js +14 -0
  35. package/dist/lib/output.d.ts +1 -0
  36. package/dist/lib/output.js +6 -0
  37. package/dist/lib/passthrough.d.ts +21 -0
  38. package/dist/lib/passthrough.js +26 -0
  39. package/dist/lib/tokens.d.ts +0 -5
  40. package/dist/lib/tokens.js +0 -5
  41. package/package.json +1 -1
@@ -17,6 +17,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
17
17
  import { join } from "node:path";
18
18
  import { confirm } from "@inquirer/prompts";
19
19
  import * as output from "../lib/output.js";
20
+ import { getErrorMessage } from "../lib/errors.js";
20
21
  import { getApiUrl, requireApiKey, CLI_USER_AGENT } from "../lib/config.js";
21
22
  // ── Config file ─────────────────────────────────────────────────────────
22
23
  const CONFIG_FILENAME = "bankr.webhooks.json";
@@ -487,7 +488,7 @@ export async function webhooksDeployCommand(name) {
487
488
  }
488
489
  catch (err) {
489
490
  spin.fail("Deploy failed");
490
- output.error(err instanceof Error ? err.message : String(err));
491
+ output.error(getErrorMessage(err));
491
492
  process.exit(1);
492
493
  }
493
494
  }
@@ -507,7 +508,9 @@ export async function webhooksListCommand() {
507
508
  const status = w.status === "active"
508
509
  ? output.fmt.success("active")
509
510
  : output.fmt.warn(w.status);
510
- const mode = w.readOnly ? output.fmt.dim("read-only") : output.fmt.warn("writes");
511
+ const mode = w.readOnly
512
+ ? output.fmt.dim("read-only")
513
+ : output.fmt.warn("writes");
511
514
  console.log(` ${output.fmt.brand(w.name)} ${status} v${w.version} ${mode} ${w.totalInvocations} invocations`);
512
515
  if (w.description)
513
516
  output.dim(` ${w.description}`);
@@ -515,7 +518,7 @@ export async function webhooksListCommand() {
515
518
  }
516
519
  catch (err) {
517
520
  spin.fail("Failed to list webhooks");
518
- output.error(err instanceof Error ? err.message : String(err));
521
+ output.error(getErrorMessage(err));
519
522
  process.exit(1);
520
523
  }
521
524
  }
@@ -533,7 +536,7 @@ export async function webhooksPauseResumeCommand(name, action) {
533
536
  }
534
537
  catch (err) {
535
538
  spin.fail(`Failed to ${action} ${name}`);
536
- output.error(err instanceof Error ? err.message : String(err));
539
+ output.error(getErrorMessage(err));
537
540
  process.exit(1);
538
541
  }
539
542
  }
@@ -556,14 +559,16 @@ export async function webhooksDeleteCommand(name) {
556
559
  }
557
560
  catch (err) {
558
561
  spin.fail(`Failed to delete ${name}`);
559
- output.error(err instanceof Error ? err.message : String(err));
562
+ output.error(getErrorMessage(err));
560
563
  process.exit(1);
561
564
  }
562
565
  }
563
566
  export async function webhooksLogsCommand(name) {
564
567
  const spin = output.spinner(`Fetching invocations for ${name}...`);
565
568
  try {
566
- const res = await fetch(`${getApiUrl()}/webhooks/${name}/logs?limit=25`, { headers: authHeaders() });
569
+ const res = await fetch(`${getApiUrl()}/webhooks/${name}/logs?limit=25`, {
570
+ headers: authHeaders(),
571
+ });
567
572
  const result = await handleResponse(res);
568
573
  spin.stop();
569
574
  if (result.logs.length === 0) {
@@ -582,7 +587,7 @@ export async function webhooksLogsCommand(name) {
582
587
  }
583
588
  catch (err) {
584
589
  spin.fail("Failed to fetch logs");
585
- output.error(err instanceof Error ? err.message : String(err));
590
+ output.error(getErrorMessage(err));
586
591
  process.exit(1);
587
592
  }
588
593
  }
@@ -611,7 +616,7 @@ export async function webhooksEnvSetCommand(keyValue) {
611
616
  }
612
617
  catch (err) {
613
618
  spin.fail(`Failed to set ${key}`);
614
- output.error(err instanceof Error ? err.message : String(err));
619
+ output.error(getErrorMessage(err));
615
620
  process.exit(1);
616
621
  }
617
622
  }
@@ -632,7 +637,7 @@ export async function webhooksEnvListCommand() {
632
637
  }
633
638
  catch (err) {
634
639
  spin.fail("Failed to list env vars");
635
- output.error(err instanceof Error ? err.message : String(err));
640
+ output.error(getErrorMessage(err));
636
641
  process.exit(1);
637
642
  }
638
643
  }
@@ -645,7 +650,7 @@ export async function webhooksEnvUnsetCommand(key) {
645
650
  }
646
651
  catch (err) {
647
652
  spin.fail(`Failed to remove ${key}`);
648
- output.error(err instanceof Error ? err.message : String(err));
653
+ output.error(getErrorMessage(err));
649
654
  process.exit(1);
650
655
  }
651
656
  }
@@ -2,6 +2,7 @@ import { existsSync } from "fs";
2
2
  import { getApiKey, getApiUrl, getConfigPath, isCustomApiUrl, } from "../lib/config.js";
3
3
  import { getUserInfo } from "../lib/api.js";
4
4
  import * as output from "../lib/output.js";
5
+ import { getErrorMessage } from "../lib/errors.js";
5
6
  export async function whoamiCommand() {
6
7
  const apiKey = getApiKey();
7
8
  const apiUrl = getApiUrl();
@@ -35,7 +36,7 @@ export async function whoamiCommand() {
35
36
  }
36
37
  }
37
38
  catch (err) {
38
- spin.fail(`Could not reach Bankr API: ${err.message}`);
39
+ spin.fail(`Could not reach Bankr API: ${getErrorMessage(err)}`);
39
40
  return;
40
41
  }
41
42
  // Fetch user profile info
@@ -69,7 +70,7 @@ export async function whoamiCommand() {
69
70
  output.label("Score", `${score}${rankStr}`);
70
71
  }
71
72
  catch (err) {
72
- profileSpin.fail(`Could not fetch account info: ${err.message}`);
73
+ profileSpin.fail(`Could not fetch account info: ${getErrorMessage(err)}`);
73
74
  }
74
75
  }
75
76
  //# sourceMappingURL=whoami.js.map
@@ -62,6 +62,9 @@ export declare function x402EnvUnsetCommand(key: string): Promise<void>;
62
62
  export declare function x402SchemaCommand(url: string, opts?: {
63
63
  raw?: boolean;
64
64
  }): Promise<void>;
65
+ export declare function checkAdvertisedPrice(advertisedUsd: number | null, callerCapUsd: number): string | null;
66
+ export declare function parseAdvertisedPrice(price: string, currency: string): number | null;
67
+ export declare function outboundMaxPayment(callerCapUsd: number, advertisedUsd: number | null): number;
65
68
  export declare function x402CallCommand(url: string, opts?: {
66
69
  method?: string;
67
70
  body?: string;
@@ -20,12 +20,19 @@ import { join } from "node:path";
20
20
  import chalk from "chalk";
21
21
  import { input, select, confirm } from "@inquirer/prompts";
22
22
  import * as output from "../lib/output.js";
23
+ import { getErrorMessage } from "../lib/errors.js";
23
24
  import { getApiUrl, requireApiKey, CLI_USER_AGENT } from "../lib/config.js";
24
25
  // ── Config file helpers ─────────────────────────────────────────────────
25
26
  const CONFIG_FILENAME = "bankr.x402.json";
26
27
  function findProjectRoot() {
27
28
  return process.cwd();
28
29
  }
30
+ // Config values come from user-edited JSON cast without validation, so fields
31
+ // feeding select() defaults are plain strings; narrow them to the offered
32
+ // choices (select's default must match the literal union of choice values).
33
+ function pickDefault(value, allowed) {
34
+ return allowed.find((v) => v === value);
35
+ }
29
36
  function loadConfigFile(projectRoot) {
30
37
  const candidates = [
31
38
  join(projectRoot, CONFIG_FILENAME),
@@ -237,9 +244,7 @@ export default async function handler(req: Request): Promise<Response> {
237
244
  };
238
245
  // Add to config
239
246
  let config = loadConfigFile(root);
240
- if (!config) {
241
- config = { services: {} };
242
- }
247
+ config || (config = { services: {} });
243
248
  config.services[name] = {
244
249
  price: "0.001",
245
250
  description: `${name} service`,
@@ -257,9 +262,7 @@ export default async function handler(req: Request): Promise<Response> {
257
262
  export async function x402ConfigureCommand(name) {
258
263
  const root = findProjectRoot();
259
264
  let config = loadConfigFile(root);
260
- if (!config) {
261
- config = { services: {} };
262
- }
265
+ config || (config = { services: {} });
263
266
  const existing = config.services[name] ?? { price: "0.001" };
264
267
  const description = await input({
265
268
  message: "Service description:",
@@ -272,12 +275,14 @@ export async function x402ConfigureCommand(name) {
272
275
  theme: output.bankrTheme,
273
276
  });
274
277
  const currency = "USDC";
278
+ const networkDefault = pickDefault(existing.network, ["base"]) ?? "base";
275
279
  const network = await select({
276
280
  message: "Network:",
277
281
  choices: [{ name: "Base", value: "base" }],
278
- default: existing.network ?? "base",
282
+ default: networkDefault,
279
283
  theme: output.bankrTheme,
280
284
  });
285
+ const methodDefault = pickDefault(existing.methods?.[0], ["GET", "POST", "*"]) ?? "GET";
281
286
  const method = await select({
282
287
  message: "HTTP method:",
283
288
  choices: [
@@ -285,7 +290,7 @@ export async function x402ConfigureCommand(name) {
285
290
  { name: "POST — JSON body", value: "POST" },
286
291
  { name: "Any — accept all methods", value: "*" },
287
292
  ],
288
- default: existing.methods?.[0] ?? "GET",
293
+ default: methodDefault,
289
294
  theme: output.bankrTheme,
290
295
  });
291
296
  const paymentScheme = await select({
@@ -327,9 +332,7 @@ export async function x402DeployCommand(name) {
327
332
  }
328
333
  // Load or bootstrap config
329
334
  let config = loadConfigFile(root);
330
- if (!config) {
331
- config = { services: {} };
332
- }
335
+ config || (config = { services: {} });
333
336
  // Discover services
334
337
  const { readdirSync, statSync } = await import("node:fs");
335
338
  const entries = readdirSync(x402Dir);
@@ -422,7 +425,7 @@ export async function x402DeployCommand(name) {
422
425
  }
423
426
  catch (err) {
424
427
  spin.fail("Deploy failed");
425
- output.error(err instanceof Error ? err.message : String(err));
428
+ output.error(getErrorMessage(err));
426
429
  process.exit(1);
427
430
  }
428
431
  }
@@ -452,7 +455,7 @@ export async function x402ListCommand() {
452
455
  }
453
456
  catch (err) {
454
457
  spin.fail("Failed to list endpoints");
455
- output.error(err instanceof Error ? err.message : String(err));
458
+ output.error(getErrorMessage(err));
456
459
  process.exit(1);
457
460
  }
458
461
  }
@@ -473,7 +476,7 @@ export async function x402PauseResumeCommand(name, action) {
473
476
  }
474
477
  catch (err) {
475
478
  spin.fail(`Failed to ${action} ${name}`);
476
- output.error(err instanceof Error ? err.message : String(err));
479
+ output.error(getErrorMessage(err));
477
480
  process.exit(1);
478
481
  }
479
482
  }
@@ -499,7 +502,7 @@ export async function x402DeleteCommand(name) {
499
502
  }
500
503
  catch (err) {
501
504
  spin.fail(`Failed to delete ${name}`);
502
- output.error(err instanceof Error ? err.message : String(err));
505
+ output.error(getErrorMessage(err));
503
506
  process.exit(1);
504
507
  }
505
508
  }
@@ -533,7 +536,7 @@ export async function x402RevenueCommand(name) {
533
536
  }
534
537
  catch (err) {
535
538
  spin.fail("Failed to fetch revenue");
536
- output.error(err instanceof Error ? err.message : String(err));
539
+ output.error(getErrorMessage(err));
537
540
  process.exit(1);
538
541
  }
539
542
  }
@@ -564,7 +567,7 @@ export async function x402EnvSetCommand(keyValue) {
564
567
  }
565
568
  catch (err) {
566
569
  spin.fail(`Failed to set ${key}`);
567
- output.error(err instanceof Error ? err.message : String(err));
570
+ output.error(getErrorMessage(err));
568
571
  process.exit(1);
569
572
  }
570
573
  }
@@ -589,7 +592,7 @@ export async function x402EnvListCommand() {
589
592
  }
590
593
  catch (err) {
591
594
  spin.fail("Failed to list env vars");
592
- output.error(err instanceof Error ? err.message : String(err));
595
+ output.error(getErrorMessage(err));
593
596
  process.exit(1);
594
597
  }
595
598
  }
@@ -608,7 +611,7 @@ export async function x402EnvUnsetCommand(key) {
608
611
  }
609
612
  catch (err) {
610
613
  spin.fail(`Failed to remove ${key}`);
611
- output.error(err instanceof Error ? err.message : String(err));
614
+ output.error(getErrorMessage(err));
612
615
  process.exit(1);
613
616
  }
614
617
  }
@@ -875,7 +878,7 @@ export async function x402SchemaCommand(url, opts = {}) {
875
878
  }
876
879
  catch (err) {
877
880
  spin.fail("Schema lookup failed");
878
- output.error(err instanceof Error ? err.message : String(err));
881
+ output.error(getErrorMessage(err));
879
882
  process.exit(1);
880
883
  }
881
884
  }
@@ -998,6 +1001,32 @@ async function fetchSchemaForInteractive(url) {
998
1001
  return null;
999
1002
  }
1000
1003
  // ── Call ──────────────────────────────────────────────────────────────
1004
+ // The caller's --max-payment is the only value ever sent as the payment cap;
1005
+ // an endpoint-advertised price may never raise it — fail closed instead.
1006
+ // Exported for tests.
1007
+ export function checkAdvertisedPrice(advertisedUsd, callerCapUsd) {
1008
+ if (advertisedUsd !== null && advertisedUsd > callerCapUsd) {
1009
+ return `Endpoint requires $${advertisedUsd} but --max-payment is $${callerCapUsd}. Re-run with a higher --max-payment (up to 10) to allow it.`;
1010
+ }
1011
+ return null;
1012
+ }
1013
+ // Advertised prices that are non-positive, unparseable, or token-denominated
1014
+ // (non-USD currency) are treated as unknown: only a USD value can safely feed
1015
+ // the USD cap clamp or the fail-closed comparison. Exported for tests.
1016
+ export function parseAdvertisedPrice(price, currency) {
1017
+ const upper = currency.toUpperCase();
1018
+ if (upper !== "USDC" && upper !== "USD")
1019
+ return null;
1020
+ const parsed = parseFloat(price);
1021
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
1022
+ }
1023
+ // The cap we send: never above the caller's --max-payment, and never above the
1024
+ // advertised price the user was shown and confirmed. Exported for tests.
1025
+ export function outboundMaxPayment(callerCapUsd, advertisedUsd) {
1026
+ return advertisedUsd !== null
1027
+ ? Math.min(advertisedUsd, callerCapUsd)
1028
+ : callerCapUsd;
1029
+ }
1001
1030
  export async function x402CallCommand(url, opts = {}) {
1002
1031
  if (!url) {
1003
1032
  output.error("Usage: bankr x402 call <url> [--method POST] [--body '{}']");
@@ -1010,7 +1039,8 @@ export async function x402CallCommand(url, opts = {}) {
1010
1039
  output.error("--max-payment must be between 0 and 10 (USD)");
1011
1040
  process.exit(1);
1012
1041
  }
1013
- // Interactive mode: fetch schema and prompt for input values
1042
+ // Endpoint-advertised price. Shown at confirm time; the outbound cap is
1043
+ // clamped to min(advertised, caller's maxPaymentUsd) — see outboundMaxPayment.
1014
1044
  let resolvedPrice = null;
1015
1045
  if (opts.interactive) {
1016
1046
  const schema = await fetchSchemaForInteractive(url);
@@ -1024,7 +1054,12 @@ export async function x402CallCommand(url, opts = {}) {
1024
1054
  console.log(` ${chalk.dim("Price")} ${chalk.green(`$${schema.price} ${schema.currency}`)}`);
1025
1055
  console.log();
1026
1056
  // Use the endpoint's actual price and preferred method
1027
- resolvedPrice = parseFloat(schema.price);
1057
+ resolvedPrice = parseAdvertisedPrice(schema.price, schema.currency);
1058
+ const capError = checkAdvertisedPrice(resolvedPrice, maxPaymentUsd);
1059
+ if (capError) {
1060
+ output.error(capError);
1061
+ process.exit(1);
1062
+ }
1028
1063
  if (schema.methods.length > 0) {
1029
1064
  method = schema.methods.includes("POST") ? "POST" : schema.methods[0];
1030
1065
  }
@@ -1040,7 +1075,7 @@ export async function x402CallCommand(url, opts = {}) {
1040
1075
  : `${key} ${chalk.dim(`(${typedProp.type}, optional)`)}`;
1041
1076
  const hint = typedProp.description ?? "";
1042
1077
  // Enum fields → select prompt
1043
- if (typedProp.enum && typedProp.enum.length > 0) {
1078
+ if (typedProp.enum?.length) {
1044
1079
  const selected = await select({
1045
1080
  message: `${label}${hint ? ` — ${chalk.dim(hint)}` : ""}`,
1046
1081
  choices: typedProp.enum.map((v) => ({
@@ -1097,6 +1132,7 @@ export async function x402CallCommand(url, opts = {}) {
1097
1132
  // No schema available — fallback: prompt for method and body
1098
1133
  output.warn("No schema found for this endpoint. Falling back to manual input.");
1099
1134
  console.log();
1135
+ const manualMethodDefault = pickDefault(method, ["GET", "POST", "PUT", "DELETE"]) ?? "GET";
1100
1136
  method = await select({
1101
1137
  message: "HTTP method",
1102
1138
  choices: [
@@ -1105,7 +1141,7 @@ export async function x402CallCommand(url, opts = {}) {
1105
1141
  { name: "PUT", value: "PUT" },
1106
1142
  { name: "DELETE", value: "DELETE" },
1107
1143
  ],
1108
- default: method,
1144
+ default: manualMethodDefault,
1109
1145
  theme: output.bankrTheme,
1110
1146
  });
1111
1147
  if (method === "POST" || method === "PUT") {
@@ -1143,13 +1179,22 @@ export async function x402CallCommand(url, opts = {}) {
1143
1179
  }
1144
1180
  console.log();
1145
1181
  }
1146
- // Non-interactive: probe the endpoint to show the actual price before confirming
1147
- if (!opts.interactive && !opts.yes && resolvedPrice === null) {
1182
+ // Probe the endpoint to show the actual price before confirming. Skipped in
1183
+ // non-interactive mode, where the confirm is suppressed — --ni matches --yes.
1184
+ if (!opts.interactive &&
1185
+ !opts.yes &&
1186
+ !output.isNonInteractive() &&
1187
+ resolvedPrice === null) {
1148
1188
  const spin = output.spinner("Checking endpoint price...");
1149
1189
  const schema = await fetchSchemaForInteractive(url);
1150
1190
  spin.stop();
1151
1191
  if (schema) {
1152
- resolvedPrice = parseFloat(schema.price);
1192
+ resolvedPrice = parseAdvertisedPrice(schema.price, schema.currency);
1193
+ const capError = checkAdvertisedPrice(resolvedPrice, maxPaymentUsd);
1194
+ if (capError) {
1195
+ output.error(capError);
1196
+ process.exit(1);
1197
+ }
1153
1198
  }
1154
1199
  }
1155
1200
  if (!opts.yes && !opts.interactive && !output.isNonInteractive()) {
@@ -1184,7 +1229,7 @@ export async function x402CallCommand(url, opts = {}) {
1184
1229
  url,
1185
1230
  method,
1186
1231
  body: requestBody,
1187
- maxPaymentUsd: resolvedPrice ?? maxPaymentUsd,
1232
+ maxPaymentUsd: outboundMaxPayment(maxPaymentUsd, resolvedPrice),
1188
1233
  }),
1189
1234
  });
1190
1235
  const result = await handleResponse(res);
@@ -1229,7 +1274,7 @@ export async function x402CallCommand(url, opts = {}) {
1229
1274
  }
1230
1275
  catch (err) {
1231
1276
  spin.fail("Call failed");
1232
- output.error(err instanceof Error ? err.message : String(err));
1277
+ output.error(getErrorMessage(err));
1233
1278
  process.exit(1);
1234
1279
  }
1235
1280
  }
@@ -1276,7 +1321,7 @@ export async function x402SearchCommand(queryParts, opts = {}) {
1276
1321
  }
1277
1322
  catch (err) {
1278
1323
  spin.fail("Search failed");
1279
- output.error(err instanceof Error ? err.message : String(err));
1324
+ output.error(getErrorMessage(err));
1280
1325
  process.exit(1);
1281
1326
  }
1282
1327
  }
package/dist/lib/api.d.ts CHANGED
@@ -69,7 +69,11 @@ export declare function getUserInfo(): Promise<UserInfoResponse>;
69
69
  export interface TokenBalanceInfo {
70
70
  network: string;
71
71
  token: {
72
- balance: number;
72
+ /**
73
+ * Wire shape of `GET /wallet/portfolio`: an exact decimal string.
74
+ * Coerce with `Number(...)` before arithmetic or comparison.
75
+ */
76
+ balance: string;
73
77
  balanceUSD: number;
74
78
  baseToken: {
75
79
  name: string;
@@ -191,11 +195,14 @@ export interface SubmitResponse {
191
195
  }
192
196
  export declare function submit(request: SubmitRequest): Promise<SubmitResponse>;
193
197
  export type FeeRecipientType = "wallet" | "x" | "farcaster" | "ens";
198
+ /** Chains the deploy endpoint accepts (mirrors the API's zod enum). */
199
+ export type LaunchChain = "base" | "robinhood";
194
200
  export interface DeployTokenRequest {
195
201
  tokenName: string;
196
202
  tokenSymbol?: string;
197
203
  image?: string;
198
204
  description?: string;
205
+ chain?: LaunchChain;
199
206
  tweetUrl?: string;
200
207
  websiteUrl?: string;
201
208
  feeRecipient?: {
@@ -203,6 +210,11 @@ export interface DeployTokenRequest {
203
210
  value: string;
204
211
  };
205
212
  simulateOnly?: boolean;
213
+ /** Turn off the default 15% creator vesting (100% of supply sold into the pool). */
214
+ disableVesting?: boolean;
215
+ /** Collect all creator fees in the pool's quote token (e.g. WETH) instead of
216
+ * a mix of the launched token and the quote token. */
217
+ quoteOnlyFees?: boolean;
206
218
  }
207
219
  export interface DeployTokenResponse {
208
220
  success: boolean;
@@ -222,6 +234,8 @@ export interface CreatorFeesTokenResult {
222
234
  tokenAddress: string;
223
235
  name: string;
224
236
  symbol: string;
237
+ /** Launch chain ("base" | "robinhood"); absent on older API versions → base. */
238
+ chain?: string;
225
239
  poolId: string;
226
240
  initializer?: string;
227
241
  share: string;
@@ -259,6 +273,9 @@ export interface BeneficiaryFeesResponse {
259
273
  totalLaunches: number;
260
274
  poolsWithShares: number;
261
275
  tokens: CreatorFeesTokenResult[];
276
+ /** Server stopped the scan early — more claimable fees may exist. */
277
+ truncated?: boolean;
278
+ scanned?: number;
262
279
  }
263
280
  export interface DopplerClaimTxResponse {
264
281
  to: string;