@bankr/cli 0.3.13 → 0.3.32

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/lib/api.js CHANGED
@@ -7,19 +7,21 @@ const TERMINAL_STATUSES = [
7
7
  function isTerminalStatus(status) {
8
8
  return TERMINAL_STATUSES.includes(status);
9
9
  }
10
- function authHeaders() {
10
+ export function authHeaders() {
11
11
  return {
12
12
  "X-API-Key": requireApiKey(),
13
13
  "Content-Type": "application/json",
14
14
  "User-Agent": CLI_USER_AGENT,
15
15
  };
16
16
  }
17
- async function handleResponse(res) {
17
+ export async function handleResponse(res) {
18
18
  if (!res.ok) {
19
19
  const body = (await res
20
20
  .json()
21
21
  .catch(() => ({ message: res.statusText })));
22
- const msg = body.message || body.error || res.statusText;
22
+ const msg = (typeof body.message === "string" && body.message) ||
23
+ (typeof body.error === "string" && body.error) ||
24
+ res.statusText;
23
25
  throw new Error(`API error (${res.status}): ${msg}`);
24
26
  }
25
27
  return res.json();
@@ -32,10 +34,19 @@ export class ApiError extends Error {
32
34
  this.body = body;
33
35
  }
34
36
  }
37
+ /** Choke point for every authenticated request. Injects auth headers. */
38
+ async function authedFetch(url, init = {}) {
39
+ return fetch(url, {
40
+ ...init,
41
+ headers: {
42
+ ...authHeaders(),
43
+ ...init.headers,
44
+ },
45
+ });
46
+ }
35
47
  export async function submitPrompt(prompt, threadId, maxMode) {
36
- const res = await fetch(`${getApiUrl()}/agent/prompt`, {
48
+ const res = await authedFetch(`${getApiUrl()}/agent/prompt`, {
37
49
  method: "POST",
38
- headers: authHeaders(),
39
50
  body: JSON.stringify({
40
51
  prompt,
41
52
  ...(threadId && { threadId }),
@@ -52,15 +63,12 @@ export async function submitPrompt(prompt, threadId, maxMode) {
52
63
  return res.json();
53
64
  }
54
65
  export async function getJobStatus(jobId) {
55
- const res = await fetch(`${getApiUrl()}/agent/job/${jobId}`, {
56
- headers: authHeaders(),
57
- });
66
+ const res = await authedFetch(`${getApiUrl()}/agent/job/${jobId}`);
58
67
  return handleResponse(res);
59
68
  }
60
69
  export async function cancelJob(jobId) {
61
- const res = await fetch(`${getApiUrl()}/agent/job/${jobId}/cancel`, {
70
+ const res = await authedFetch(`${getApiUrl()}/agent/job/${jobId}/cancel`, {
62
71
  method: "POST",
63
- headers: authHeaders(),
64
72
  });
65
73
  return handleResponse(res);
66
74
  }
@@ -76,9 +84,7 @@ export async function validateApiKey() {
76
84
  }
77
85
  }
78
86
  export async function getUserInfo() {
79
- const res = await fetch(`${getApiUrl()}/wallet/me`, {
80
- headers: authHeaders(),
81
- });
87
+ const res = await authedFetch(`${getApiUrl()}/wallet/me`);
82
88
  return handleResponse(res);
83
89
  }
84
90
  export async function getPortfolio(opts = {}) {
@@ -90,7 +96,7 @@ export async function getPortfolio(opts = {}) {
90
96
  if (opts.include?.length)
91
97
  query.set("include", opts.include.join(","));
92
98
  const qs = query.toString();
93
- const res = await fetch(`${getApiUrl()}/wallet/portfolio${qs ? `?${qs}` : ""}`, { headers: authHeaders() });
99
+ const res = await authedFetch(`${getApiUrl()}/wallet/portfolio${qs ? `?${qs}` : ""}`);
94
100
  return handleResponse(res);
95
101
  }
96
102
  /** @deprecated Use getPortfolio instead */
@@ -110,25 +116,22 @@ export async function pollJob(jobId, opts = {}) {
110
116
  throw new Error(`Polling timed out after ${maxAttempts} attempts`);
111
117
  }
112
118
  export async function sign(request) {
113
- const res = await fetch(`${getApiUrl()}/wallet/sign`, {
119
+ const res = await authedFetch(`${getApiUrl()}/wallet/sign`, {
114
120
  method: "POST",
115
- headers: authHeaders(),
116
121
  body: JSON.stringify(request),
117
122
  });
118
123
  return handleResponse(res);
119
124
  }
120
125
  export async function submit(request) {
121
- const res = await fetch(`${getApiUrl()}/wallet/submit`, {
126
+ const res = await authedFetch(`${getApiUrl()}/wallet/submit`, {
122
127
  method: "POST",
123
- headers: authHeaders(),
124
128
  body: JSON.stringify(request),
125
129
  });
126
130
  return handleResponse(res);
127
131
  }
128
132
  export async function deployToken(request) {
129
- const res = await fetch(`${getApiUrl()}/token-launches/deploy`, {
133
+ const res = await authedFetch(`${getApiUrl()}/token-launches/deploy`, {
130
134
  method: "POST",
131
- headers: authHeaders(),
132
135
  body: JSON.stringify(request),
133
136
  });
134
137
  return handleResponse(res);
@@ -239,9 +242,8 @@ export async function getTokenCreatorFees(tokenAddress, days) {
239
242
  * to work through the deprecation window.
240
243
  */
241
244
  export async function buildDopplerClaimTx(tokenAddress) {
242
- const res = await fetch(`${getApiUrl()}/agent/doppler/claim`, {
245
+ const res = await authedFetch(`${getApiUrl()}/agent/doppler/claim`, {
243
246
  method: "POST",
244
- headers: authHeaders(),
245
247
  body: JSON.stringify({ tokenAddress }),
246
248
  });
247
249
  return handleResponse(res);
@@ -253,17 +255,14 @@ export async function buildDopplerClaimTx(tokenAddress) {
253
255
  * Replaces the two-step `buildDopplerClaimTx` + `submit` flow.
254
256
  */
255
257
  export async function claimTokenLaunchFees(tokenAddress) {
256
- const res = await fetch(`${getApiUrl()}/token-launches/${tokenAddress}/fees/claim`, {
258
+ const res = await authedFetch(`${getApiUrl()}/token-launches/${tokenAddress}/fees/claim`, {
257
259
  method: "POST",
258
- headers: authHeaders(),
259
260
  body: JSON.stringify({}),
260
261
  });
261
262
  return handleResponse(res);
262
263
  }
263
264
  export async function getOwnProfiles() {
264
- const res = await fetch(`${getApiUrl()}/agent/profile?multi=true`, {
265
- headers: authHeaders(),
266
- });
265
+ const res = await authedFetch(`${getApiUrl()}/agent/profile?multi=true`);
267
266
  return handleResponse(res);
268
267
  }
269
268
  /** @deprecated Use getOwnProfiles() — returns first profile for backward compat */
@@ -272,32 +271,28 @@ export async function getOwnProfile() {
272
271
  return profiles[0];
273
272
  }
274
273
  export async function createProfile(data) {
275
- const res = await fetch(`${getApiUrl()}/agent/profile?multi=true`, {
274
+ const res = await authedFetch(`${getApiUrl()}/agent/profile?multi=true`, {
276
275
  method: "POST",
277
- headers: authHeaders(),
278
276
  body: JSON.stringify(data),
279
277
  });
280
278
  return handleResponse(res);
281
279
  }
282
280
  export async function updateProfile(slug, data) {
283
- const res = await fetch(`${getApiUrl()}/agent/profile/${encodeURIComponent(slug)}`, {
281
+ const res = await authedFetch(`${getApiUrl()}/agent/profile/${encodeURIComponent(slug)}`, {
284
282
  method: "PUT",
285
- headers: authHeaders(),
286
283
  body: JSON.stringify(data),
287
284
  });
288
285
  return handleResponse(res);
289
286
  }
290
287
  export async function deleteProfile(slug) {
291
- const res = await fetch(`${getApiUrl()}/agent/profile/${encodeURIComponent(slug)}`, {
288
+ const res = await authedFetch(`${getApiUrl()}/agent/profile/${encodeURIComponent(slug)}`, {
292
289
  method: "DELETE",
293
- headers: authHeaders(),
294
290
  });
295
291
  return handleResponse(res);
296
292
  }
297
293
  export async function addProjectUpdate(slug, data) {
298
- const res = await fetch(`${getApiUrl()}/agent/profile/${encodeURIComponent(slug)}/update`, {
294
+ const res = await authedFetch(`${getApiUrl()}/agent/profile/${encodeURIComponent(slug)}/update`, {
299
295
  method: "POST",
300
- headers: authHeaders(),
301
296
  body: JSON.stringify(data),
302
297
  });
303
298
  return handleResponse(res);
@@ -314,25 +309,22 @@ export async function searchTokens(query, chainId) {
314
309
  return handleResponse(res);
315
310
  }
316
311
  export async function transfer(request) {
317
- const res = await fetch(`${getApiUrl()}/wallet/transfer`, {
312
+ const res = await authedFetch(`${getApiUrl()}/wallet/transfer`, {
318
313
  method: "POST",
319
- headers: authHeaders(),
320
314
  body: JSON.stringify(request),
321
315
  });
322
316
  return handleResponse(res);
323
317
  }
324
318
  export async function getSwapQuote(request) {
325
- const res = await fetch(`${getApiUrl()}/wallet/swap-quote`, {
319
+ const res = await authedFetch(`${getApiUrl()}/wallet/swap-quote`, {
326
320
  method: "POST",
327
- headers: authHeaders(),
328
321
  body: JSON.stringify(request),
329
322
  });
330
323
  return handleResponse(res);
331
324
  }
332
325
  export async function executeSwap(request) {
333
- const res = await fetch(`${getApiUrl()}/wallet/swap`, {
326
+ const res = await authedFetch(`${getApiUrl()}/wallet/swap`, {
334
327
  method: "POST",
335
- headers: authHeaders(),
336
328
  body: JSON.stringify(request),
337
329
  });
338
330
  return handleResponse(res);
@@ -347,9 +339,8 @@ export async function resolveRecipient(value, type) {
347
339
  return handleResponse(res);
348
340
  }
349
341
  export async function x402Pay(request) {
350
- const res = await fetch(`${getApiUrl()}/wallet/x402-pay`, {
342
+ const res = await authedFetch(`${getApiUrl()}/wallet/x402-pay`, {
351
343
  method: "POST",
352
- headers: authHeaders(),
353
344
  body: JSON.stringify(request),
354
345
  });
355
346
  return handleResponse(res);
@@ -5,6 +5,7 @@ const EXPLORERS = {
5
5
  name: "Blockscout",
6
6
  baseUrl: "https://robinhoodchain.blockscout.com",
7
7
  },
8
+ 42161: { name: "Arbiscan", baseUrl: "https://arbiscan.io" },
8
9
  };
9
10
  /** Unknown chain ids fall back to Basescan (pre-multichain behavior). */
10
11
  export function txExplorer(chainId, txHash) {
@@ -6,6 +6,7 @@ export declare const fmt: {
6
6
  readonly dim: import("chalk").ChalkInstance;
7
7
  readonly success: import("chalk").ChalkInstance;
8
8
  readonly warn: import("chalk").ChalkInstance;
9
+ readonly magic: import("chalk").ChalkInstance;
9
10
  };
10
11
  export declare const bankrTheme: {
11
12
  prefix: string;
@@ -21,6 +22,10 @@ export declare function brand(msg: string): void;
21
22
  export declare function brandBold(msg: string): void;
22
23
  export declare function success(msg: string): void;
23
24
  export declare function error(msg: string): void;
25
+ /** Collapses the error-then-exit epilogue every command repeats. */
26
+ export declare function fatal(message: string): never;
27
+ /** Same epilogue, for the spinner-driven variant that reports a caught error. */
28
+ export declare function failWith(spinner: Ora, label: string, err: unknown): never;
24
29
  export declare function warn(msg: string): void;
25
30
  export declare function info(msg: string): void;
26
31
  export declare function blank(): void;
@@ -1,8 +1,14 @@
1
1
  import chalk from "chalk";
2
2
  import ora from "ora";
3
+ import { getErrorMessage } from "./errors.js";
3
4
  const BRAND_HEX = "#FF613D";
4
5
  const brandColor = chalk.hex(BRAND_HEX);
5
6
  const brandColorBold = brandColor.bold;
7
+ /**
8
+ * The web's `--background-magic-color-bg-magic` token, so the Private (TEE)
9
+ * tier reads as the same thing in the terminal as it does in the catalogue.
10
+ */
11
+ const MAGIC_HEX = "#8B5CF6";
6
12
  /** String formatters (return colored strings without logging). */
7
13
  export const fmt = {
8
14
  brand: brandColor,
@@ -10,6 +16,7 @@ export const fmt = {
10
16
  dim: chalk.dim,
11
17
  success: chalk.green,
12
18
  warn: chalk.yellow,
19
+ magic: chalk.hex(MAGIC_HEX),
13
20
  };
14
21
  export const bankrTheme = {
15
22
  prefix: brandColor("▸"),
@@ -33,6 +40,17 @@ export function success(msg) {
33
40
  export function error(msg) {
34
41
  console.error(chalk.red(`✗ ${msg}`));
35
42
  }
43
+ /** Collapses the error-then-exit epilogue every command repeats. */
44
+ export function fatal(message) {
45
+ error(message);
46
+ process.exit(1);
47
+ }
48
+ /** Same epilogue, for the spinner-driven variant that reports a caught error. */
49
+ export function failWith(spinner, label, err) {
50
+ spinner.fail(label);
51
+ error(getErrorMessage(err));
52
+ process.exit(1);
53
+ }
36
54
  export function warn(msg) {
37
55
  console.log(chalk.yellow(`⚠ ${msg}`));
38
56
  }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Everything the user typed after `name`, forwarded verbatim to a spawned tool.
3
+ *
4
+ * Read off argv rather than commander's parsed args so the tool's own flags
5
+ * (`--model`, `--resume`, …) reach it untouched — `allowUnknownOption()` alone
6
+ * isn't enough, since commander still consumes and reorders what it recognizes.
7
+ * This is what lets `--model "claude-opus-5[1m]"` survive.
8
+ *
9
+ * The search starts at index 2 to skip `[node, script]`, so the command token
10
+ * is always matched ahead of any later occurrence in prompt text.
11
+ */
12
+ export declare function passthroughArgs(name: string, argv?: string[]): string[];
13
+ /**
14
+ * Whether the forwarded args are just asking the tool to print its own help.
15
+ *
16
+ * Such a run makes no gateway request, so the launcher spawns the tool
17
+ * directly — skipping the auth gate (which would otherwise exit with "Not
18
+ * authenticated") and the "Launching…" banner.
19
+ */
20
+ export declare function isHelpRequest(args: string[]): boolean;
21
+ //# sourceMappingURL=passthrough.d.ts.map
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Everything the user typed after `name`, forwarded verbatim to a spawned tool.
3
+ *
4
+ * Read off argv rather than commander's parsed args so the tool's own flags
5
+ * (`--model`, `--resume`, …) reach it untouched — `allowUnknownOption()` alone
6
+ * isn't enough, since commander still consumes and reorders what it recognizes.
7
+ * This is what lets `--model "claude-opus-5[1m]"` survive.
8
+ *
9
+ * The search starts at index 2 to skip `[node, script]`, so the command token
10
+ * is always matched ahead of any later occurrence in prompt text.
11
+ */
12
+ export function passthroughArgs(name, argv = process.argv) {
13
+ const idx = argv.indexOf(name, 2);
14
+ return idx >= 0 ? argv.slice(idx + 1) : [];
15
+ }
16
+ /**
17
+ * Whether the forwarded args are just asking the tool to print its own help.
18
+ *
19
+ * Such a run makes no gateway request, so the launcher spawns the tool
20
+ * directly — skipping the auth gate (which would otherwise exit with "Not
21
+ * authenticated") and the "Launching…" banner.
22
+ */
23
+ export function isHelpRequest(args) {
24
+ return args.some((arg) => arg === "--help" || arg === "-h");
25
+ }
26
+ //# sourceMappingURL=passthrough.js.map
@@ -1,8 +1,3 @@
1
- /**
2
- * Native-token sentinel (zero address). The API detects + sanitizes native
3
- * tokens from this, so callers send it instead of a real contract address.
4
- */
5
- export declare const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
6
1
  /** Shorten an address for display, e.g. `0x8335…2913`. */
7
2
  export declare function shortenAddress(address: string): string;
8
3
  /**
@@ -1,11 +1,6 @@
1
1
  import { isAddress } from "viem";
2
2
  import { searchTokens } from "./api.js";
3
3
  import { CHAIN_IDS } from "./chains.js";
4
- /**
5
- * Native-token sentinel (zero address). The API detects + sanitizes native
6
- * tokens from this, so callers send it instead of a real contract address.
7
- */
8
- export const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
9
4
  /** Shorten an address for display, e.g. `0x8335…2913`. */
10
5
  export function shortenAddress(address) {
11
6
  return `${address.slice(0, 6)}…${address.slice(-4)}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bankr/cli",
3
- "version": "0.3.13",
3
+ "version": "0.3.32",
4
4
  "description": "Official CLI for the Bankr AI agent platform",
5
5
  "type": "module",
6
6
  "bin": {