@bankr/cli 0.3.32 → 0.3.35

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/README.md CHANGED
@@ -94,6 +94,10 @@ bankr launch --name "TESTCOIN" --image "https://example.com/img.png" \
94
94
  # Quick launch (name only, skip confirmation)
95
95
  bankr launch --name "TESTCOIN" -y
96
96
 
97
+ # Pair the pool with a tokenized stock instead of WETH (Robinhood Chain or Base)
98
+ bankr launch quotes --chain robinhood # list the quote tokens you can pair with
99
+ bankr launch --name "TESTCOIN" --chain robinhood --quote TSLA -y
100
+
97
101
  # Fee recipient types: x, farcaster, ens, wallet
98
102
  bankr launch --name "TESTCOIN" --fee "vitalik.eth" --fee-type ens -y
99
103
  bankr launch --name "TESTCOIN" --fee "0x1234..." --fee-type wallet -y
@@ -174,12 +178,12 @@ Credentials are stored in `~/.bankr/config.json`.
174
178
 
175
179
  Environment variables override stored values:
176
180
 
177
- | Variable | Description |
178
- |----------|-------------|
179
- | `BANKR_API_KEY` | API key (overrides stored key) |
180
- | `BANKR_API_URL` | API URL (default: `https://api.bankr.bot`) |
181
+ | Variable | Description |
182
+ | --------------- | ---------------------------------------------------------- |
183
+ | `BANKR_API_KEY` | API key (overrides stored key) |
184
+ | `BANKR_API_URL` | API URL (default: `https://api.bankr.bot`) |
181
185
  | `BANKR_LLM_KEY` | LLM gateway key (falls back to `BANKR_API_KEY` if not set) |
182
- | `BANKR_LLM_URL` | LLM gateway URL (default: `https://llm.bankr.bot`) |
186
+ | `BANKR_LLM_URL` | LLM gateway URL (default: `https://llm.bankr.bot`) |
183
187
 
184
188
  ## API Key
185
189
 
package/dist/cli.js CHANGED
@@ -15,6 +15,7 @@ import { passthroughArgs } from "./lib/passthrough.js";
15
15
  import { claudeCommand, creditsCommand, creditsAddCommand, creditsAutoCommand, modelsCommand, opencodeCommand, setupClaudeCodeCommand, setupCursorCommand, setupOpenclawCommand, setupOpenCodeCommand, } from "./commands/llm.js";
16
16
  import { feesCommand, feesClaimCommand, feesClaimWalletCommand, } from "./commands/fees.js";
17
17
  import { launchCommand } from "./commands/launch.js";
18
+ import { launchQuotesCommand } from "./commands/launchQuotes.js";
18
19
  import { loginCommand } from "./commands/login.js";
19
20
  import { logoutCommand } from "./commands/logout.js";
20
21
  import { promptCommand } from "./commands/prompt.js";
@@ -337,7 +338,7 @@ agentCmd
337
338
  .description("Show all Bankr AI agent skills with examples")
338
339
  .action(skillsCommand);
339
340
  program.commandsGroup("Tokens");
340
- program
341
+ const launchCmd = program
341
342
  .command("launch")
342
343
  .description("Launch a token on Base, Robinhood Chain or Arbitrum (interactive wizard)")
343
344
  .optionsGroup("Token")
@@ -345,6 +346,7 @@ program
345
346
  .option("--symbol <symbol>", "Token symbol (default: auto-generated from name)")
346
347
  .option("--image <url>", "Token image URL")
347
348
  .option("--chain <chain>", "Chain to launch on: base, robinhood, arbitrum (default: base)")
349
+ .option("--quote <token>", 'Quote token to pair the pool with, e.g. a tokenized stock: a symbol or address from "bankr launch quotes" (default: WETH)')
348
350
  .option("--no-vesting", "Turn off the default 15% creator vesting (sell 100% of supply into the pool)")
349
351
  .optionsGroup("Links")
350
352
  .option("--tweet <url>", "Associated tweet URL")
@@ -362,6 +364,7 @@ program
362
364
  symbol: opts.symbol,
363
365
  image: opts.image,
364
366
  chain: opts.chain,
367
+ quote: opts.quote,
365
368
  vesting: opts.vesting,
366
369
  tweet: opts.tweet,
367
370
  website: opts.website,
@@ -372,6 +375,14 @@ program
372
375
  simulate: opts.simulate,
373
376
  });
374
377
  });
378
+ launchCmd
379
+ .command("quotes")
380
+ .description("List the quote tokens a launch can pair with on a chain (WETH, tokenized stocks, more)")
381
+ .option("--chain <chain>", "Chain to list for: base, robinhood, arbitrum (default: base)")
382
+ .option("--json", "Output raw JSON")
383
+ // The parent `launch` also owns --chain and, like every command here, parses
384
+ // its options from anywhere on the line — so read the merged view.
385
+ .action((_opts, cmd) => launchQuotesCommand(cmd.optsWithGlobals()));
375
386
  program.commandsGroup("Tokens");
376
387
  const feesCmd = program
377
388
  .command("fees [address]")
@@ -502,7 +513,7 @@ llmSetupCmd
502
513
  .command("openclaw")
503
514
  .description("OpenClaw config")
504
515
  .option("--install", "Write config to ~/.openclaw/openclaw.json")
505
- .option("--images", "Also route image generation (gpt-image-2) through the gateway — takes over OpenClaw's 'openai' provider slot")
516
+ .option("--images", "Also route image generation (gpt-image-2.5-flare) through the gateway — takes over OpenClaw's 'openai' provider slot")
506
517
  .action(setupOpenclawCommand);
507
518
  llmSetupCmd
508
519
  .command("opencode")
@@ -1,8 +1,11 @@
1
+ import { type LaunchChain } from "../lib/api.js";
1
2
  export interface LaunchOptions {
2
3
  name?: string;
3
4
  symbol?: string;
4
5
  image?: string;
5
6
  chain?: string;
7
+ /** --quote: symbol or address of the quote token to pair the pool with. */
8
+ quote?: string;
6
9
  /** Commander --no-vesting flag: false = vesting explicitly turned off. */
7
10
  vesting?: boolean;
8
11
  tweet?: string;
@@ -14,5 +17,7 @@ export interface LaunchOptions {
14
17
  yes?: boolean;
15
18
  simulate?: boolean;
16
19
  }
20
+ export declare function launchChainLabel(chain: LaunchChain): string;
21
+ export declare function parseLaunchChain(value?: string): LaunchChain | undefined;
17
22
  export declare function launchCommand(options: LaunchOptions): Promise<void>;
18
23
  //# sourceMappingURL=launch.d.ts.map
@@ -1,9 +1,10 @@
1
- import { confirm, input, select } from "@inquirer/prompts";
2
- import { deployToken, } from "../lib/api.js";
1
+ import { confirm, input, search, select } from "@inquirer/prompts";
2
+ import { deployToken, getLaunchQuoteTokens, } from "../lib/api.js";
3
3
  import { emitCESP } from "../lib/cesp/engine.js";
4
4
  import { requireApiKey } from "../lib/config.js";
5
5
  import * as output from "../lib/output.js";
6
6
  import { getErrorMessage } from "../lib/errors.js";
7
+ import { quoteTokenAvailabilityNote, quoteTokenDeployFields, resolveQuoteToken, } from "../lib/quoteTokens.js";
7
8
  const VALID_FEE_TYPES = ["x", "farcaster", "ens", "wallet"];
8
9
  const VALID_CHAINS = ["base", "robinhood", "arbitrum"];
9
10
  const CHAIN_LABELS = {
@@ -11,10 +12,10 @@ const CHAIN_LABELS = {
11
12
  robinhood: "Robinhood Chain",
12
13
  arbitrum: "Arbitrum",
13
14
  };
14
- function chainLabel(chain) {
15
+ export function launchChainLabel(chain) {
15
16
  return CHAIN_LABELS[chain];
16
17
  }
17
- function parseChain(value) {
18
+ export function parseLaunchChain(value) {
18
19
  if (!value)
19
20
  return undefined;
20
21
  const lower = value.toLowerCase();
@@ -33,6 +34,60 @@ function parseFeeType(value) {
33
34
  output.warn(`Unknown fee type "${value}". Valid types: ${VALID_FEE_TYPES.join(", ")}. Defaulting to "x".`);
34
35
  return "x";
35
36
  }
37
+ function quoteTokenChoiceName(option) {
38
+ const note = quoteTokenAvailabilityNote(option);
39
+ const base = option.isDefault
40
+ ? `${option.symbol} (default)`
41
+ : `${option.symbol} — ${option.name}`;
42
+ return note ? `${base} [${note}]` : base;
43
+ }
44
+ /**
45
+ * Resolve the quote token for the pool: --quote wins; otherwise the wizard
46
+ * offers the chain's list. Non-interactive runs without --quote keep the
47
+ * chain default and never hit the network.
48
+ */
49
+ async function collectQuoteToken(chain, requested) {
50
+ if (!requested && output.isNonInteractive())
51
+ return undefined;
52
+ let listing;
53
+ try {
54
+ listing = await getLaunchQuoteTokens(chain);
55
+ }
56
+ catch (err) {
57
+ if (requested) {
58
+ output.fatal(`Could not load quote tokens for ${launchChainLabel(chain)}: ${getErrorMessage(err)}`);
59
+ }
60
+ output.warn(`Could not load quote tokens for ${launchChainLabel(chain)}; pairing with the chain default.`);
61
+ return undefined;
62
+ }
63
+ const { provider, quoteTokens } = listing;
64
+ if (requested) {
65
+ const option = resolveQuoteToken(quoteTokens, requested);
66
+ if (!option) {
67
+ output.fatal(`"${requested}" is not a quote token you can pair with on ${launchChainLabel(chain)}. Run "bankr launch quotes --chain ${chain}" to see the list.`);
68
+ }
69
+ return option.isDefault ? undefined : { option, provider };
70
+ }
71
+ // Nothing to choose from — the chain only offers its default.
72
+ if (quoteTokens.length <= 1)
73
+ return undefined;
74
+ const option = await search({
75
+ message: "Quote token to pair the pool with? (type to filter)",
76
+ source: (term) => {
77
+ const key = (term ?? "").trim().toLowerCase().replace(/^\$/, "");
78
+ return quoteTokens
79
+ .filter((candidate) => !key ||
80
+ candidate.symbol.toLowerCase().includes(key) ||
81
+ candidate.name.toLowerCase().includes(key))
82
+ .map((candidate) => ({
83
+ name: quoteTokenChoiceName(candidate),
84
+ value: candidate,
85
+ }));
86
+ },
87
+ theme: output.bankrTheme,
88
+ });
89
+ return option.isDefault ? undefined : { option, provider };
90
+ }
36
91
  function feeTypeLabel(type) {
37
92
  switch (type) {
38
93
  case "x":
@@ -66,12 +121,12 @@ async function collectInteractive(options) {
66
121
  (await promptOrSkip("Image URL for your token (press Enter to skip):"));
67
122
  // Chain: --chain flag wins; otherwise interactive select (default Base).
68
123
  // Non-interactive runs without --chain launch on Base.
69
- let chain = parseChain(options.chain);
124
+ let chain = parseLaunchChain(options.chain);
70
125
  if (!chain && !output.isNonInteractive()) {
71
126
  chain = await select({
72
127
  message: "Which chain do you want to launch on?",
73
128
  choices: VALID_CHAINS.map((value) => ({
74
- name: chainLabel(value),
129
+ name: launchChainLabel(value),
75
130
  value,
76
131
  })),
77
132
  default: "base",
@@ -79,6 +134,8 @@ async function collectInteractive(options) {
79
134
  });
80
135
  }
81
136
  chain ?? (chain = "base");
137
+ const quoteToken = await collectQuoteToken(chain, options.quote);
138
+ const quoteSymbol = quoteToken?.option.symbol ?? "WETH";
82
139
  // Vesting: --no-vesting wins; otherwise interactive select (default: keep
83
140
  // the 15% creator vesting). Non-interactive runs keep vesting on.
84
141
  let disableVesting = options.vesting === false;
@@ -98,7 +155,7 @@ async function collectInteractive(options) {
98
155
  let quoteOnlyFees = options.quoteOnlyFees === true;
99
156
  if (!quoteOnlyFees && !output.isNonInteractive()) {
100
157
  quoteOnlyFees = await select({
101
- message: "Fee collection? By default creator fees accrue as a mix of your token and the pool's quote token (e.g. WETH).",
158
+ message: `Fee collection? By default creator fees accrue as a mix of your token and the pool's quote token (${quoteSymbol}).`,
102
159
  choices: [
103
160
  { name: "Both tokens (default)", value: false },
104
161
  { name: "Quote token only", value: true },
@@ -132,6 +189,7 @@ async function collectInteractive(options) {
132
189
  tokenSymbol: tokenSymbol.trim(),
133
190
  imageUrl: imageUrl.trim(),
134
191
  chain,
192
+ quoteToken,
135
193
  tweetUrl: tweetUrl.trim(),
136
194
  websiteUrl: websiteUrl.trim(),
137
195
  feeRecipient: feeRecipient.trim(),
@@ -159,17 +217,32 @@ export async function launchCommand(options) {
159
217
  output.keyValue("Fee recipient", state.feeRecipient
160
218
  ? `${state.feeRecipient} (${feeTypeLabel(state.feeRecipientType)})`
161
219
  : "(self)");
162
- output.keyValue("Chain", chainLabel(state.chain));
220
+ output.keyValue("Chain", launchChainLabel(state.chain));
221
+ const quoteSymbol = state.quoteToken?.option.symbol ?? "WETH";
222
+ output.keyValue("Quote token", state.quoteToken
223
+ ? `${quoteSymbol} — ${state.quoteToken.option.name} (${state.quoteToken.option.address})`
224
+ : "WETH (default)");
163
225
  output.keyValue("Vesting", state.disableVesting
164
226
  ? "Off (100% of supply sold into the pool)"
165
227
  : "15% to fee recipient over 1 year (default)");
166
228
  output.keyValue("Fee collection", state.quoteOnlyFees
167
- ? "Quote token only (e.g. WETH)"
229
+ ? `Quote token only (${quoteSymbol})`
168
230
  : "Both tokens (default)");
169
231
  if (options.simulate) {
170
232
  output.keyValue("Mode", "Simulation (dry run)");
171
233
  }
172
234
  console.log();
235
+ const quoteNote = state.quoteToken
236
+ ? quoteTokenAvailabilityNote(state.quoteToken.option)
237
+ : undefined;
238
+ if (quoteNote === "thin liquidity") {
239
+ output.warn(`${quoteSymbol} has thin liquidity right now — the pool may be hard to trade until more arrives.`);
240
+ console.log();
241
+ }
242
+ else if (quoteNote) {
243
+ output.warn(`${quoteSymbol} is ${quoteNote}; the API may refuse this pairing until it is live.`);
244
+ console.log();
245
+ }
173
246
  if (!options.yes && !output.isNonInteractive()) {
174
247
  const proceed = await confirm({
175
248
  message: options.simulate
@@ -200,6 +273,8 @@ export async function launchCommand(options) {
200
273
  simulateOnly: options.simulate,
201
274
  disableVesting: state.disableVesting || undefined,
202
275
  quoteOnlyFees: state.quoteOnlyFees || undefined,
276
+ ...(state.quoteToken &&
277
+ quoteTokenDeployFields(state.quoteToken.option, state.quoteToken.provider)),
203
278
  });
204
279
  const elapsed = output.formatDuration(Date.now() - startTime);
205
280
  spin.succeed(result.simulated
@@ -0,0 +1,7 @@
1
+ export interface LaunchQuotesOptions {
2
+ chain?: string;
3
+ json?: boolean;
4
+ }
5
+ /** `bankr launch quotes` — the quote tokens a launch on a chain can pair with. */
6
+ export declare function launchQuotesCommand(opts: LaunchQuotesOptions): Promise<void>;
7
+ //# sourceMappingURL=launchQuotes.d.ts.map
@@ -0,0 +1,49 @@
1
+ import { getLaunchQuoteTokens } from "../lib/api.js";
2
+ import * as output from "../lib/output.js";
3
+ import { getErrorMessage } from "../lib/errors.js";
4
+ import { quoteTokenAvailabilityNote, quoteTokenGroupLabel, } from "../lib/quoteTokens.js";
5
+ import { launchChainLabel, parseLaunchChain } from "./launch.js";
6
+ const GROUP_ORDER = [
7
+ "Default",
8
+ "Majors",
9
+ "More tokens",
10
+ "Stocks",
11
+ ];
12
+ /** `bankr launch quotes` — the quote tokens a launch on a chain can pair with. */
13
+ export async function launchQuotesCommand(opts) {
14
+ const chain = parseLaunchChain(opts.chain) ?? "base";
15
+ if (opts.json) {
16
+ try {
17
+ console.log(JSON.stringify(await getLaunchQuoteTokens(chain), null, 2));
18
+ }
19
+ catch (err) {
20
+ output.fatal(getErrorMessage(err));
21
+ }
22
+ return;
23
+ }
24
+ const spin = output.spinner(`Loading quote tokens for ${launchChainLabel(chain)}...`);
25
+ let listing;
26
+ try {
27
+ listing = await getLaunchQuoteTokens(chain);
28
+ }
29
+ catch (err) {
30
+ output.failWith(spin, "Could not load quote tokens", err);
31
+ }
32
+ spin.succeed(`${listing.quoteTokens.length} quote token(s) on ${launchChainLabel(chain)}`);
33
+ const symbolWidth = Math.max(...listing.quoteTokens.map((option) => option.symbol.length), 4);
34
+ for (const group of GROUP_ORDER) {
35
+ const members = listing.quoteTokens.filter((option) => quoteTokenGroupLabel(option) === group);
36
+ if (members.length === 0)
37
+ continue;
38
+ console.log();
39
+ output.brandBold(` ${group} (${members.length})`);
40
+ for (const option of members) {
41
+ const note = quoteTokenAvailabilityNote(option);
42
+ const label = `${option.symbol.padEnd(symbolWidth)} ${option.name}`;
43
+ console.log(` ${label} ${output.fmt.dim(option.address)}${note ? ` ${output.fmt.dim(`[${note}]`)}` : ""}`);
44
+ }
45
+ }
46
+ console.log();
47
+ output.dim(`Pair a launch with one: bankr launch --chain ${chain} --quote <symbol or address>`);
48
+ }
49
+ //# sourceMappingURL=launchQuotes.js.map
@@ -212,6 +212,28 @@ const GATEWAY_MODELS = [
212
212
  cost: { input: 0.15, output: 0.6, cacheRead: 0, cacheWrite: 0 },
213
213
  },
214
214
  // OpenAI
215
+ {
216
+ id: "gpt-image-2.5-flare",
217
+ name: "GPT Image 2.5 Flare",
218
+ owned_by: "openai",
219
+ contextWindow: 400000,
220
+ maxTokens: 16384,
221
+ input: IMAGE_INPUT,
222
+ output: ["image"],
223
+ // Image model — served via /v1/images/generations; output rate is per
224
+ // million image tokens.
225
+ cost: { input: 5.0, output: 30.0, cacheRead: 1.25, cacheWrite: 0 },
226
+ },
227
+ {
228
+ id: "gpt-image-2.5-sunburst",
229
+ name: "GPT Image 2.5 Sunburst",
230
+ owned_by: "openai",
231
+ contextWindow: 400000,
232
+ maxTokens: 16384,
233
+ input: IMAGE_INPUT,
234
+ output: ["image"],
235
+ cost: { input: 5.0, output: 30.0, cacheRead: 1.25, cacheWrite: 0 },
236
+ },
215
237
  {
216
238
  id: "gpt-6-astra",
217
239
  name: "GPT 6 Astra",
@@ -258,7 +280,7 @@ const GATEWAY_MODELS = [
258
280
  output: ["image"],
259
281
  // Image model — served via /v1/images/generations; output rate is per
260
282
  // million image tokens.
261
- cost: { input: 5.0, output: 30.0, cacheRead: 0, cacheWrite: 0 },
283
+ cost: { input: 5.0, output: 30.0, cacheRead: 1.25, cacheWrite: 0 },
262
284
  },
263
285
  {
264
286
  id: "gpt-5.5",
@@ -384,6 +406,15 @@ const GATEWAY_MODELS = [
384
406
  removed_at: "2026-06-17T00:00:00.000Z",
385
407
  },
386
408
  },
409
+ {
410
+ id: "deepseek-v4.1-flash",
411
+ name: "DeepSeek V4.1 Flash",
412
+ owned_by: "deepseek",
413
+ contextWindow: 1048576,
414
+ maxTokens: 384000,
415
+ input: IMAGE_INPUT,
416
+ cost: { input: 0.3, output: 1.2, cacheRead: 0.006, cacheWrite: 0 },
417
+ },
387
418
  {
388
419
  id: "deepseek-v4-pro-0813",
389
420
  name: "DeepSeek V4 Pro 0813",
@@ -1283,7 +1314,7 @@ export async function setupOpenclawCommand(opts) {
1283
1314
  ? { baseUrl: imageBaseUrl, apiKey: llmKey ?? "${BANKR_API_KEY}" }
1284
1315
  : null;
1285
1316
  const imageGenerationModel = opts.images
1286
- ? { primary: "openai/gpt-image-2", timeoutMs: 180000 }
1317
+ ? { primary: "openai/gpt-image-2.5-flare", timeoutMs: 180000 }
1287
1318
  : null;
1288
1319
  const warnImagesSlot = () => {
1289
1320
  if (opts.images)
@@ -36,9 +36,11 @@ const VALID_MAX_MODE_MODELS = new Set([
36
36
  // Grok (OpenRouter)
37
37
  "grok-4.6",
38
38
  "grok-4.5",
39
- // DeepSeek (OpenRouter)
39
+ // DeepSeek (OpenRouter) — v4.1-flash is its own tier at `balanced`
40
+ // ($0.30/$1.20, 3.3x under the V4 Pro card), not the `light` flash line.
40
41
  "deepseek-v4-pro-0813",
41
42
  "deepseek-v4-pro",
43
+ "deepseek-v4.1-flash",
42
44
  // Qwen (OpenRouter)
43
45
  "qwen3.8-max",
44
46
  "qwen3.7-max",
package/dist/lib/api.d.ts CHANGED
@@ -199,6 +199,8 @@ export declare function submit(request: SubmitRequest): Promise<SubmitResponse>;
199
199
  export type FeeRecipientType = "wallet" | "x" | "farcaster" | "ens";
200
200
  /** Chains the deploy endpoint accepts (mirrors the API's zod enum). */
201
201
  export type LaunchChain = "base" | "robinhood" | "arbitrum";
202
+ /** Launch providers the deploy endpoint knows (mirrors the API's zod enum). */
203
+ export type LaunchProvider = "doppler" | "bankr_v3";
202
204
  export interface DeployTokenRequest {
203
205
  tokenName: string;
204
206
  tokenSymbol?: string;
@@ -217,7 +219,43 @@ export interface DeployTokenRequest {
217
219
  /** Collect all creator fees in the pool's quote token (e.g. WETH) instead of
218
220
  * a mix of the launched token and the quote token. */
219
221
  quoteOnlyFees?: boolean;
222
+ /** Pin the launch provider; sent alongside a quote-token pick so the API
223
+ * never resolves the pairing against a different provider. */
224
+ provider?: LaunchProvider;
225
+ /** Quote the pool in a tokenized stock (Robinhood Chain / Base, Doppler). */
226
+ pairedStockAddress?: string;
227
+ /** Quote the pool in one of the fixed Base allowlist tokens (Doppler). */
228
+ pairedTokenAddress?: string;
229
+ /** Bankr Launch v3 options; `quoteAddress` picks the pool's quote token. */
230
+ launchV3?: {
231
+ quoteAddress?: string;
232
+ };
220
233
  }
234
+ /** Deploy-body field that selects a quote token, as reported by the API. */
235
+ export type LaunchQuoteTokenDeployField = "pairedStockAddress" | "pairedTokenAddress" | "launchV3.quoteAddress";
236
+ export interface LaunchQuoteTokenOption {
237
+ address: string;
238
+ symbol: string;
239
+ name: string;
240
+ kind: "major" | "stable" | "project" | "wrapper" | "stock";
241
+ isDefault: boolean;
242
+ /** null = the chain default (omit every pairing field). */
243
+ deployField: LaunchQuoteTokenDeployField | null;
244
+ /** Stocks only: advisory thin-pool verdict, null when unmeasured. */
245
+ illiquid?: boolean | null;
246
+ /** Base allowlist only: reviewed-liquidity gate. */
247
+ readiness?: "live" | "pending" | "unknown";
248
+ }
249
+ export interface LaunchQuoteTokensResponse {
250
+ chain: LaunchChain;
251
+ provider: LaunchProvider;
252
+ quoteTokens: LaunchQuoteTokenOption[];
253
+ }
254
+ /**
255
+ * Every quote token a new launch on `chain` can pair with, the default first.
256
+ * Unauthenticated — calls the public endpoint directly.
257
+ */
258
+ export declare function getLaunchQuoteTokens(chain: LaunchChain): Promise<LaunchQuoteTokensResponse>;
221
259
  export interface DeployTokenResponse {
222
260
  success: boolean;
223
261
  tokenAddress: string;
package/dist/lib/api.js CHANGED
@@ -129,6 +129,14 @@ export async function submit(request) {
129
129
  });
130
130
  return handleResponse(res);
131
131
  }
132
+ /**
133
+ * Every quote token a new launch on `chain` can pair with, the default first.
134
+ * Unauthenticated — calls the public endpoint directly.
135
+ */
136
+ export async function getLaunchQuoteTokens(chain) {
137
+ const res = await fetch(`${getApiUrl()}/token-launches/quote-tokens?chain=${chain}`, { headers: { "User-Agent": CLI_USER_AGENT } });
138
+ return handleResponse(res);
139
+ }
132
140
  export async function deployToken(request) {
133
141
  const res = await authedFetch(`${getApiUrl()}/token-launches/deploy`, {
134
142
  method: "POST",
@@ -7,6 +7,7 @@ export const CHAIN_LABELS = {
7
7
  arbitrum: "Arbitrum",
8
8
  bnb: "BNB Chain",
9
9
  robinhood: "Robinhood Chain",
10
+ arc: "Arc",
10
11
  solana: "Solana",
11
12
  };
12
13
  export const VALID_CHAINS = new Set([
@@ -18,6 +19,7 @@ export const VALID_CHAINS = new Set([
18
19
  "arbitrum",
19
20
  "bnb",
20
21
  "robinhood",
22
+ "arc",
21
23
  "solana",
22
24
  ]);
23
25
  export const CHAIN_IDS = {
@@ -29,6 +31,7 @@ export const CHAIN_IDS = {
29
31
  arbitrum: 42161,
30
32
  bnb: 56,
31
33
  robinhood: 4663,
34
+ arc: 5042,
32
35
  };
33
36
  export const NATIVE_SYMBOLS = {
34
37
  base: "ETH",
@@ -39,5 +42,6 @@ export const NATIVE_SYMBOLS = {
39
42
  polygon: "POL",
40
43
  bnb: "BNB",
41
44
  robinhood: "ETH",
45
+ arc: "USDC",
42
46
  };
43
47
  //# sourceMappingURL=chains.js.map
@@ -0,0 +1,15 @@
1
+ import type { DeployTokenRequest, LaunchProvider, LaunchQuoteTokenOption } from "./api.js";
2
+ /** Match a `--quote` value (symbol or address) against the API's list. */
3
+ export declare function resolveQuoteToken(options: readonly LaunchQuoteTokenOption[], query: string): LaunchQuoteTokenOption | undefined;
4
+ export type QuoteTokenDeployFields = Pick<DeployTokenRequest, "pairedStockAddress" | "pairedTokenAddress" | "launchV3" | "provider">;
5
+ /**
6
+ * The deploy-body fields that select `option`. The provider is pinned with
7
+ * every non-default pick so a rollout can't move the launch to a provider
8
+ * that ignores the field.
9
+ */
10
+ export declare function quoteTokenDeployFields(option: LaunchQuoteTokenOption, provider: LaunchProvider): QuoteTokenDeployFields;
11
+ export type QuoteTokenGroupLabel = "Default" | "Majors" | "More tokens" | "Stocks";
12
+ export declare function quoteTokenGroupLabel(option: LaunchQuoteTokenOption): QuoteTokenGroupLabel;
13
+ /** Short caveat to print next to an option, or undefined when it's clean. */
14
+ export declare function quoteTokenAvailabilityNote(option: LaunchQuoteTokenOption): string | undefined;
15
+ //# sourceMappingURL=quoteTokens.d.ts.map
@@ -0,0 +1,53 @@
1
+ function normalize(query) {
2
+ return query.trim().toLowerCase().replace(/^\$/, "");
3
+ }
4
+ /** Match a `--quote` value (symbol or address) against the API's list. */
5
+ export function resolveQuoteToken(options, query) {
6
+ const key = normalize(query);
7
+ if (!key)
8
+ return undefined;
9
+ return options.find((option) => option.symbol.toLowerCase() === key ||
10
+ option.address.toLowerCase() === key);
11
+ }
12
+ /**
13
+ * The deploy-body fields that select `option`. The provider is pinned with
14
+ * every non-default pick so a rollout can't move the launch to a provider
15
+ * that ignores the field.
16
+ */
17
+ export function quoteTokenDeployFields(option, provider) {
18
+ switch (option.deployField) {
19
+ case null:
20
+ return {};
21
+ case "pairedStockAddress":
22
+ return { pairedStockAddress: option.address, provider };
23
+ case "pairedTokenAddress":
24
+ return { pairedTokenAddress: option.address, provider };
25
+ case "launchV3.quoteAddress":
26
+ return { launchV3: { quoteAddress: option.address }, provider };
27
+ }
28
+ }
29
+ export function quoteTokenGroupLabel(option) {
30
+ if (option.isDefault)
31
+ return "Default";
32
+ switch (option.kind) {
33
+ case "major":
34
+ case "stable":
35
+ return "Majors";
36
+ case "project":
37
+ case "wrapper":
38
+ return "More tokens";
39
+ case "stock":
40
+ return "Stocks";
41
+ }
42
+ }
43
+ /** Short caveat to print next to an option, or undefined when it's clean. */
44
+ export function quoteTokenAvailabilityNote(option) {
45
+ if (option.illiquid === true)
46
+ return "thin liquidity";
47
+ if (option.readiness === "pending")
48
+ return "not ready yet";
49
+ if (option.readiness === "unknown")
50
+ return "readiness unknown";
51
+ return undefined;
52
+ }
53
+ //# sourceMappingURL=quoteTokens.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bankr/cli",
3
- "version": "0.3.32",
3
+ "version": "0.3.35",
4
4
  "description": "Official CLI for the Bankr AI agent platform",
5
5
  "type": "module",
6
6
  "bin": {