@bankr/cli 0.3.32 → 0.3.37
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 +11 -5
- package/dist/cli.js +20 -3
- package/dist/commands/launch.d.ts +5 -0
- package/dist/commands/launch.js +84 -9
- package/dist/commands/launchQuotes.d.ts +7 -0
- package/dist/commands/launchQuotes.js +49 -0
- package/dist/commands/llm.js +35 -4
- package/dist/commands/login.d.ts +15 -0
- package/dist/commands/login.js +34 -11
- package/dist/commands/prompt.js +3 -1
- package/dist/lib/api.d.ts +39 -0
- package/dist/lib/api.js +8 -0
- package/dist/lib/chains.js +4 -0
- package/dist/lib/quoteTokens.d.ts +15 -0
- package/dist/lib/quoteTokens.js +53 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -94,6 +94,12 @@ 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 or another listed quote token 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
|
+
bankr launch --name "TESTCOIN" --chain robinhood --quote musebook -y
|
|
101
|
+
bankr launch --name "TESTCOIN" --chain robinhood --quote BNKR -y # the Robinhood Chain BNKR contract
|
|
102
|
+
|
|
97
103
|
# Fee recipient types: x, farcaster, ens, wallet
|
|
98
104
|
bankr launch --name "TESTCOIN" --fee "vitalik.eth" --fee-type ens -y
|
|
99
105
|
bankr launch --name "TESTCOIN" --fee "0x1234..." --fee-type wallet -y
|
|
@@ -174,12 +180,12 @@ Credentials are stored in `~/.bankr/config.json`.
|
|
|
174
180
|
|
|
175
181
|
Environment variables override stored values:
|
|
176
182
|
|
|
177
|
-
| Variable
|
|
178
|
-
|
|
179
|
-
| `BANKR_API_KEY` | API key (overrides stored key)
|
|
180
|
-
| `BANKR_API_URL` | API URL (default: `https://api.bankr.bot`)
|
|
183
|
+
| Variable | Description |
|
|
184
|
+
| --------------- | ---------------------------------------------------------- |
|
|
185
|
+
| `BANKR_API_KEY` | API key (overrides stored key) |
|
|
186
|
+
| `BANKR_API_URL` | API URL (default: `https://api.bankr.bot`) |
|
|
181
187
|
| `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`)
|
|
188
|
+
| `BANKR_LLM_URL` | LLM gateway URL (default: `https://llm.bankr.bot`) |
|
|
183
189
|
|
|
184
190
|
## API Key
|
|
185
191
|
|
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";
|
|
@@ -125,8 +126,10 @@ loginCmd
|
|
|
125
126
|
.option("--accept-terms", "Accept Terms of Service (skips prompt)")
|
|
126
127
|
.option("--key-name <name>", "API key name (default: CLI)")
|
|
127
128
|
.optionsGroup("API Permissions")
|
|
128
|
-
.option("--read-
|
|
129
|
+
.option("--read-only", "Restrict the API key to read operations")
|
|
130
|
+
.option("--read-write", "Allow transactions (the default for new keys)")
|
|
129
131
|
.option("--no-wallet-api", "Disable Wallet API (enabled by default)")
|
|
132
|
+
.option("--no-agent-api", "Disable Agent API (enabled by default)")
|
|
130
133
|
.option("--no-token-launch", "Disable Token Launch API (enabled by default)")
|
|
131
134
|
.option("--llm", "Enable LLM gateway on the API key")
|
|
132
135
|
.optionsGroup("Security")
|
|
@@ -141,8 +144,10 @@ loginCmd
|
|
|
141
144
|
code: opts.code,
|
|
142
145
|
acceptTerms: opts.acceptTerms,
|
|
143
146
|
keyName: opts.keyName,
|
|
147
|
+
readOnly: opts.readOnly,
|
|
144
148
|
readWrite: opts.readWrite,
|
|
145
149
|
walletApi: opts.walletApi,
|
|
150
|
+
agentApi: opts.agentApi,
|
|
146
151
|
tokenLaunch: opts.tokenLaunch,
|
|
147
152
|
llm: opts.llm,
|
|
148
153
|
allowedIps: opts.allowedIps,
|
|
@@ -157,6 +162,7 @@ loginCmd
|
|
|
157
162
|
.optionsGroup("API Permissions")
|
|
158
163
|
.option("--read-write", "Disable read-only mode (allow transactions)")
|
|
159
164
|
.option("--no-wallet-api", "Disable Wallet API (enabled by default)")
|
|
165
|
+
.option("--no-agent-api", "Disable Agent API (enabled by default)")
|
|
160
166
|
.option("--no-token-launch", "Disable Token Launch API (enabled by default)")
|
|
161
167
|
.optionsGroup("Security")
|
|
162
168
|
.option("--allowed-ips <ips>", "Comma-separated IP/CIDR allowlist, e.g. 1.2.3.4,10.0.0.0/24")
|
|
@@ -170,6 +176,7 @@ loginCmd
|
|
|
170
176
|
keyName: opts.keyName,
|
|
171
177
|
readWrite: opts.readWrite,
|
|
172
178
|
walletApi: opts.walletApi,
|
|
179
|
+
agentApi: opts.agentApi,
|
|
173
180
|
tokenLaunch: opts.tokenLaunch,
|
|
174
181
|
allowedIps: opts.allowedIps,
|
|
175
182
|
allowedRecipients: opts.allowedRecipients,
|
|
@@ -337,7 +344,7 @@ agentCmd
|
|
|
337
344
|
.description("Show all Bankr AI agent skills with examples")
|
|
338
345
|
.action(skillsCommand);
|
|
339
346
|
program.commandsGroup("Tokens");
|
|
340
|
-
program
|
|
347
|
+
const launchCmd = program
|
|
341
348
|
.command("launch")
|
|
342
349
|
.description("Launch a token on Base, Robinhood Chain or Arbitrum (interactive wizard)")
|
|
343
350
|
.optionsGroup("Token")
|
|
@@ -345,6 +352,7 @@ program
|
|
|
345
352
|
.option("--symbol <symbol>", "Token symbol (default: auto-generated from name)")
|
|
346
353
|
.option("--image <url>", "Token image URL")
|
|
347
354
|
.option("--chain <chain>", "Chain to launch on: base, robinhood, arbitrum (default: base)")
|
|
355
|
+
.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
356
|
.option("--no-vesting", "Turn off the default 15% creator vesting (sell 100% of supply into the pool)")
|
|
349
357
|
.optionsGroup("Links")
|
|
350
358
|
.option("--tweet <url>", "Associated tweet URL")
|
|
@@ -362,6 +370,7 @@ program
|
|
|
362
370
|
symbol: opts.symbol,
|
|
363
371
|
image: opts.image,
|
|
364
372
|
chain: opts.chain,
|
|
373
|
+
quote: opts.quote,
|
|
365
374
|
vesting: opts.vesting,
|
|
366
375
|
tweet: opts.tweet,
|
|
367
376
|
website: opts.website,
|
|
@@ -372,6 +381,14 @@ program
|
|
|
372
381
|
simulate: opts.simulate,
|
|
373
382
|
});
|
|
374
383
|
});
|
|
384
|
+
launchCmd
|
|
385
|
+
.command("quotes")
|
|
386
|
+
.description("List the quote tokens a launch can pair with on a chain (WETH, tokenized stocks, more)")
|
|
387
|
+
.option("--chain <chain>", "Chain to list for: base, robinhood, arbitrum (default: base)")
|
|
388
|
+
.option("--json", "Output raw JSON")
|
|
389
|
+
// The parent `launch` also owns --chain and, like every command here, parses
|
|
390
|
+
// its options from anywhere on the line — so read the merged view.
|
|
391
|
+
.action((_opts, cmd) => launchQuotesCommand(cmd.optsWithGlobals()));
|
|
375
392
|
program.commandsGroup("Tokens");
|
|
376
393
|
const feesCmd = program
|
|
377
394
|
.command("fees [address]")
|
|
@@ -502,7 +519,7 @@ llmSetupCmd
|
|
|
502
519
|
.command("openclaw")
|
|
503
520
|
.description("OpenClaw config")
|
|
504
521
|
.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")
|
|
522
|
+
.option("--images", "Also route image generation (gpt-image-2.5-flare) through the gateway — takes over OpenClaw's 'openai' provider slot")
|
|
506
523
|
.action(setupOpenclawCommand);
|
|
507
524
|
llmSetupCmd
|
|
508
525
|
.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
|
package/dist/commands/launch.js
CHANGED
|
@@ -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
|
|
15
|
+
export function launchChainLabel(chain) {
|
|
15
16
|
return CHAIN_LABELS[chain];
|
|
16
17
|
}
|
|
17
|
-
function
|
|
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 =
|
|
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:
|
|
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:
|
|
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",
|
|
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
|
-
?
|
|
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
|
package/dist/commands/llm.js
CHANGED
|
@@ -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:
|
|
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",
|
|
@@ -838,10 +869,10 @@ export async function modelsCommand(opts = {}) {
|
|
|
838
869
|
output.dim(` Gateway: ${getLlmUrl()}`);
|
|
839
870
|
output.dim(` ${shown.length} model${shown.length === 1 ? "" : "s"}${view?.countSuffix ?? " available"}${live ? "" : " (cached)"}`);
|
|
840
871
|
if (!view && shown.some((m) => m.private)) {
|
|
841
|
-
output.dim(" Private (TEE) — append :private to the model id (e.g. glm-5.
|
|
872
|
+
output.dim(" Private (TEE) — append :private to the model id (e.g. glm-5.3-flash:private). List: bankr llm models --private");
|
|
842
873
|
}
|
|
843
874
|
if (!view && shown.some((m) => m.zdr)) {
|
|
844
|
-
output.dim(" Zero data retention — append :zdr to the model id (e.g. glm-5.
|
|
875
|
+
output.dim(" Zero data retention — append :zdr to the model id (e.g. glm-5.3-flash:zdr), or turn it on account-wide under Settings in the web terminal. List: bankr llm models --zdr");
|
|
845
876
|
}
|
|
846
877
|
}
|
|
847
878
|
/* ─────────────────────── bankr llm credits ─────────────────────────────────── */
|
|
@@ -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)
|
package/dist/commands/login.d.ts
CHANGED
|
@@ -11,6 +11,19 @@ interface CliAuthTokens {
|
|
|
11
11
|
/** The auth headers every authenticated CLI call sends — one place, so a new
|
|
12
12
|
* endpoint can't silently omit the access token and go unrevocable again. */
|
|
13
13
|
export declare function authHeaders(tokens: CliAuthTokens): Record<string, string>;
|
|
14
|
+
/**
|
|
15
|
+
* Maps the permission opt-out flags to the create-key body. Omitted fields
|
|
16
|
+
* are dropped by JSON.stringify so the server's API_KEY_CREATE_DEFAULTS
|
|
17
|
+
* decide them; only an explicit flag sends a value.
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveKeyPermissionOverrides(opts: {
|
|
20
|
+
readOnly?: boolean;
|
|
21
|
+
readWrite?: boolean;
|
|
22
|
+
agentApi?: boolean;
|
|
23
|
+
}): {
|
|
24
|
+
readOnly?: boolean;
|
|
25
|
+
agentApiEnabled?: boolean;
|
|
26
|
+
};
|
|
14
27
|
export declare function loginCommand(opts: {
|
|
15
28
|
apiUrl?: string;
|
|
16
29
|
apiKey?: string;
|
|
@@ -18,8 +31,10 @@ export declare function loginCommand(opts: {
|
|
|
18
31
|
code?: string;
|
|
19
32
|
acceptTerms?: boolean;
|
|
20
33
|
keyName?: string;
|
|
34
|
+
readOnly?: boolean;
|
|
21
35
|
readWrite?: boolean;
|
|
22
36
|
walletApi?: boolean;
|
|
37
|
+
agentApi?: boolean;
|
|
23
38
|
tokenLaunch?: boolean;
|
|
24
39
|
llm?: boolean;
|
|
25
40
|
llmKey?: string;
|
package/dist/commands/login.js
CHANGED
|
@@ -52,6 +52,26 @@ export function authHeaders(tokens) {
|
|
|
52
52
|
"x-access-token": tokens.accessToken,
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Maps the permission opt-out flags to the create-key body. Omitted fields
|
|
57
|
+
* are dropped by JSON.stringify so the server's API_KEY_CREATE_DEFAULTS
|
|
58
|
+
* decide them; only an explicit flag sends a value.
|
|
59
|
+
*/
|
|
60
|
+
export function resolveKeyPermissionOverrides(opts) {
|
|
61
|
+
if (opts.readOnly && opts.readWrite) {
|
|
62
|
+
throw new Error("--read-only and --read-write are mutually exclusive");
|
|
63
|
+
}
|
|
64
|
+
// Build conditionally: an own `undefined` key would clobber a value the
|
|
65
|
+
// caller set before spreading this in.
|
|
66
|
+
const overrides = {};
|
|
67
|
+
if (opts.readOnly)
|
|
68
|
+
overrides.readOnly = true;
|
|
69
|
+
else if (opts.readWrite)
|
|
70
|
+
overrides.readOnly = false;
|
|
71
|
+
if (opts.agentApi === false)
|
|
72
|
+
overrides.agentApiEnabled = false;
|
|
73
|
+
return overrides;
|
|
74
|
+
}
|
|
55
75
|
async function verifyPrivyOtp(privyConfig, email, code) {
|
|
56
76
|
const res = await fetch("https://auth.privy.io/api/v1/passwordless/authenticate", {
|
|
57
77
|
method: "POST",
|
|
@@ -266,10 +286,12 @@ async function emailLoginFlow(apiUrl, opts) {
|
|
|
266
286
|
validate: (v) => v.trim().length >= 3 ? true : "Name must be at least 3 characters.",
|
|
267
287
|
}));
|
|
268
288
|
// Fine-grained API flags. walletApi and tokenLaunch default to enabled.
|
|
269
|
-
// --read-write only
|
|
289
|
+
// --read-only/--read-write only control readOnly, not which APIs are enabled.
|
|
270
290
|
const enableWallet = opts.walletApi ?? true;
|
|
271
|
-
//
|
|
272
|
-
|
|
291
|
+
// readOnly and agentApiEnabled are only sent when a flag asks for it, so the
|
|
292
|
+
// server's API_KEY_CREATE_DEFAULTS (the bankr.bot/api-keys form) decide them.
|
|
293
|
+
// The --read-only/--read-write conflict was already rejected in loginCommand.
|
|
294
|
+
const overrides = resolveKeyPermissionOverrides(opts);
|
|
273
295
|
const enableTokenLaunch = opts.tokenLaunch ?? true;
|
|
274
296
|
const enableLlm = opts.llm ??
|
|
275
297
|
(headless
|
|
@@ -279,17 +301,13 @@ async function emailLoginFlow(apiUrl, opts) {
|
|
|
279
301
|
default: false,
|
|
280
302
|
theme: output.bankrTheme,
|
|
281
303
|
}));
|
|
282
|
-
if (opts.readWrite && !enableWallet) {
|
|
283
|
-
output.warn("--read-write has no effect when Wallet API is disabled");
|
|
284
|
-
}
|
|
285
304
|
const keySpin = output.spinner("Generating API key...");
|
|
286
305
|
let apiKeyResult;
|
|
287
306
|
try {
|
|
288
307
|
apiKeyResult = await callGenerateApiKey(apiUrl, tokens, {
|
|
289
308
|
name: keyName.trim(),
|
|
290
309
|
walletApiEnabled: enableWallet,
|
|
291
|
-
|
|
292
|
-
readOnly: opts.readWrite ? false : undefined,
|
|
310
|
+
...overrides,
|
|
293
311
|
tokenLaunchApiEnabled: enableTokenLaunch,
|
|
294
312
|
llmGatewayEnabled: enableLlm,
|
|
295
313
|
allowedIps: opts.allowedIps,
|
|
@@ -304,7 +322,7 @@ async function emailLoginFlow(apiUrl, opts) {
|
|
|
304
322
|
output.blank();
|
|
305
323
|
const features = [
|
|
306
324
|
enableWallet && "Wallet",
|
|
307
|
-
|
|
325
|
+
apiKeyResult.agentApiEnabled && "Agent",
|
|
308
326
|
enableTokenLaunch && "Token Launch",
|
|
309
327
|
enableLlm && "LLM",
|
|
310
328
|
].filter(Boolean);
|
|
@@ -321,7 +339,6 @@ async function emailLoginFlow(apiUrl, opts) {
|
|
|
321
339
|
];
|
|
322
340
|
output.dim(` Recipients: ${parts.join(", ")}`);
|
|
323
341
|
}
|
|
324
|
-
output.dim(" Agent API: enable at bankr.bot/api-keys");
|
|
325
342
|
output.dim(" Manage keys at bankr.bot/api-keys");
|
|
326
343
|
return apiKeyResult.apiKey;
|
|
327
344
|
}
|
|
@@ -372,7 +389,7 @@ async function siweLoginFlow(apiUrl, opts) {
|
|
|
372
389
|
keyName: opts.keyName ?? `SIWE-${new Date().toISOString().slice(0, 10)}`,
|
|
373
390
|
readOnly: opts.readOnly ?? false,
|
|
374
391
|
walletApiEnabled: opts.walletApi ?? true,
|
|
375
|
-
|
|
392
|
+
...resolveKeyPermissionOverrides({ agentApi: opts.agentApi }),
|
|
376
393
|
tokenLaunchApiEnabled: opts.tokenLaunch ?? true,
|
|
377
394
|
allowedIps: opts.allowedIps,
|
|
378
395
|
allowedRecipients: opts.allowedRecipients,
|
|
@@ -492,6 +509,11 @@ export async function loginCommand(opts) {
|
|
|
492
509
|
if (opts.apiKey !== undefined && !opts.apiKey.trim()) {
|
|
493
510
|
output.fatal("--api-key requires a non-empty value");
|
|
494
511
|
}
|
|
512
|
+
// Reject conflicting permission flags before any network call, so a
|
|
513
|
+
// headless step-2 login doesn't burn its one-time code on a usage error.
|
|
514
|
+
if (opts.readOnly && opts.readWrite) {
|
|
515
|
+
output.fatal("--read-only and --read-write are mutually exclusive");
|
|
516
|
+
}
|
|
495
517
|
// Non-interactive mode requires a headless flag combo. Without one, the
|
|
496
518
|
// command would hang on a prompt — fail fast with the available paths.
|
|
497
519
|
// Email step 1 (`login email <addr>` without --code) is also headless:
|
|
@@ -569,6 +591,7 @@ export async function loginCommand(opts) {
|
|
|
569
591
|
keyName: opts.keyName,
|
|
570
592
|
readOnly: !opts.readWrite,
|
|
571
593
|
walletApi: opts.walletApi,
|
|
594
|
+
agentApi: opts.agentApi,
|
|
572
595
|
tokenLaunch: opts.tokenLaunch,
|
|
573
596
|
...getParsedRestrictions(),
|
|
574
597
|
});
|
package/dist/commands/prompt.js
CHANGED
|
@@ -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,44 @@ 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 chain's fixed Doppler allowlist tokens
|
|
228
|
+
* (Base or Robinhood Chain). */
|
|
229
|
+
pairedTokenAddress?: string;
|
|
230
|
+
/** Bankr Launch v3 options; `quoteAddress` picks the pool's quote token. */
|
|
231
|
+
launchV3?: {
|
|
232
|
+
quoteAddress?: string;
|
|
233
|
+
};
|
|
220
234
|
}
|
|
235
|
+
/** Deploy-body field that selects a quote token, as reported by the API. */
|
|
236
|
+
export type LaunchQuoteTokenDeployField = "pairedStockAddress" | "pairedTokenAddress" | "launchV3.quoteAddress";
|
|
237
|
+
export interface LaunchQuoteTokenOption {
|
|
238
|
+
address: string;
|
|
239
|
+
symbol: string;
|
|
240
|
+
name: string;
|
|
241
|
+
kind: "major" | "stable" | "project" | "wrapper" | "stock";
|
|
242
|
+
isDefault: boolean;
|
|
243
|
+
/** null = the chain default (omit every pairing field). */
|
|
244
|
+
deployField: LaunchQuoteTokenDeployField | null;
|
|
245
|
+
/** Stocks only: advisory thin-pool verdict, null when unmeasured. */
|
|
246
|
+
illiquid?: boolean | null;
|
|
247
|
+
/** Doppler allowlist tokens only (pairedTokenAddress): reviewed-liquidity gate. */
|
|
248
|
+
readiness?: "live" | "pending" | "unknown";
|
|
249
|
+
}
|
|
250
|
+
export interface LaunchQuoteTokensResponse {
|
|
251
|
+
chain: LaunchChain;
|
|
252
|
+
provider: LaunchProvider;
|
|
253
|
+
quoteTokens: LaunchQuoteTokenOption[];
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Every quote token a new launch on `chain` can pair with, the default first.
|
|
257
|
+
* Unauthenticated — calls the public endpoint directly.
|
|
258
|
+
*/
|
|
259
|
+
export declare function getLaunchQuoteTokens(chain: LaunchChain): Promise<LaunchQuoteTokensResponse>;
|
|
221
260
|
export interface DeployTokenResponse {
|
|
222
261
|
success: boolean;
|
|
223
262
|
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",
|
package/dist/lib/chains.js
CHANGED
|
@@ -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
|