@bankr/cli 0.3.23 → 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 +15 -5
- package/dist/cli.js +20 -14
- package/dist/commands/balances.js +1 -2
- package/dist/commands/cancel.js +1 -4
- package/dist/commands/club.js +6 -16
- package/dist/commands/config.js +1 -2
- package/dist/commands/fees.js +19 -29
- package/dist/commands/files.js +17 -39
- package/dist/commands/launch.d.ts +5 -0
- package/dist/commands/launch.js +98 -22
- package/dist/commands/launchQuotes.d.ts +7 -0
- package/dist/commands/launchQuotes.js +49 -0
- package/dist/commands/llm.d.ts +8 -0
- package/dist/commands/llm.js +308 -68
- package/dist/commands/login.js +20 -31
- package/dist/commands/portfolio.js +1 -2
- package/dist/commands/prompt.js +28 -29
- package/dist/commands/sign.js +8 -16
- package/dist/commands/sounds.js +6 -16
- package/dist/commands/status.js +1 -4
- package/dist/commands/submit.js +12 -24
- package/dist/commands/swap.js +2 -4
- package/dist/commands/tokens.js +1 -2
- package/dist/commands/transfer.js +2 -4
- package/dist/commands/update.js +1 -2
- package/dist/commands/webhooks.js +21 -65
- package/dist/commands/whoami.js +1 -2
- package/dist/commands/x402.js +36 -100
- package/dist/lib/api.d.ts +42 -2
- package/dist/lib/api.js +10 -2
- package/dist/lib/chains.js +4 -0
- package/dist/lib/explorer.js +1 -0
- package/dist/lib/output.d.ts +4 -0
- package/dist/lib/output.js +12 -0
- package/dist/lib/quoteTokens.d.ts +15 -0
- package/dist/lib/quoteTokens.js +53 -0
- package/package.json +1 -1
package/dist/commands/launch.js
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
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
|
-
const VALID_CHAINS = ["base", "robinhood"];
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
const VALID_CHAINS = ["base", "robinhood", "arbitrum"];
|
|
10
|
+
const CHAIN_LABELS = {
|
|
11
|
+
base: "Base",
|
|
12
|
+
robinhood: "Robinhood Chain",
|
|
13
|
+
arbitrum: "Arbitrum",
|
|
14
|
+
};
|
|
15
|
+
export function launchChainLabel(chain) {
|
|
16
|
+
return CHAIN_LABELS[chain];
|
|
11
17
|
}
|
|
12
|
-
function
|
|
18
|
+
export function parseLaunchChain(value) {
|
|
13
19
|
if (!value)
|
|
14
20
|
return undefined;
|
|
15
21
|
const lower = value.toLowerCase();
|
|
@@ -17,8 +23,7 @@ function parseChain(value) {
|
|
|
17
23
|
return lower;
|
|
18
24
|
// Launching is irreversible and chain-selecting — a mistyped chain must be
|
|
19
25
|
// a hard usage error, never a silent fallback to Base.
|
|
20
|
-
output.
|
|
21
|
-
process.exit(1);
|
|
26
|
+
output.fatal(`Unknown chain "${value}". Valid chains: ${VALID_CHAINS.join(", ")}.`);
|
|
22
27
|
}
|
|
23
28
|
function parseFeeType(value) {
|
|
24
29
|
if (!value)
|
|
@@ -29,6 +34,60 @@ function parseFeeType(value) {
|
|
|
29
34
|
output.warn(`Unknown fee type "${value}". Valid types: ${VALID_FEE_TYPES.join(", ")}. Defaulting to "x".`);
|
|
30
35
|
return "x";
|
|
31
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
|
+
}
|
|
32
91
|
function feeTypeLabel(type) {
|
|
33
92
|
switch (type) {
|
|
34
93
|
case "x":
|
|
@@ -48,8 +107,7 @@ async function promptOrSkip(message) {
|
|
|
48
107
|
}
|
|
49
108
|
async function collectInteractive(options) {
|
|
50
109
|
if (output.isNonInteractive() && !options.name) {
|
|
51
|
-
output.
|
|
52
|
-
process.exit(1);
|
|
110
|
+
output.fatal("--name is required in non-interactive mode");
|
|
53
111
|
}
|
|
54
112
|
const tokenName = options.name ??
|
|
55
113
|
(await input({
|
|
@@ -63,19 +121,21 @@ async function collectInteractive(options) {
|
|
|
63
121
|
(await promptOrSkip("Image URL for your token (press Enter to skip):"));
|
|
64
122
|
// Chain: --chain flag wins; otherwise interactive select (default Base).
|
|
65
123
|
// Non-interactive runs without --chain launch on Base.
|
|
66
|
-
let chain =
|
|
124
|
+
let chain = parseLaunchChain(options.chain);
|
|
67
125
|
if (!chain && !output.isNonInteractive()) {
|
|
68
126
|
chain = await select({
|
|
69
127
|
message: "Which chain do you want to launch on?",
|
|
70
|
-
choices:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
128
|
+
choices: VALID_CHAINS.map((value) => ({
|
|
129
|
+
name: launchChainLabel(value),
|
|
130
|
+
value,
|
|
131
|
+
})),
|
|
74
132
|
default: "base",
|
|
75
133
|
theme: output.bankrTheme,
|
|
76
134
|
});
|
|
77
135
|
}
|
|
78
136
|
chain ?? (chain = "base");
|
|
137
|
+
const quoteToken = await collectQuoteToken(chain, options.quote);
|
|
138
|
+
const quoteSymbol = quoteToken?.option.symbol ?? "WETH";
|
|
79
139
|
// Vesting: --no-vesting wins; otherwise interactive select (default: keep
|
|
80
140
|
// the 15% creator vesting). Non-interactive runs keep vesting on.
|
|
81
141
|
let disableVesting = options.vesting === false;
|
|
@@ -95,7 +155,7 @@ async function collectInteractive(options) {
|
|
|
95
155
|
let quoteOnlyFees = options.quoteOnlyFees === true;
|
|
96
156
|
if (!quoteOnlyFees && !output.isNonInteractive()) {
|
|
97
157
|
quoteOnlyFees = await select({
|
|
98
|
-
message:
|
|
158
|
+
message: `Fee collection? By default creator fees accrue as a mix of your token and the pool's quote token (${quoteSymbol}).`,
|
|
99
159
|
choices: [
|
|
100
160
|
{ name: "Both tokens (default)", value: false },
|
|
101
161
|
{ name: "Quote token only", value: true },
|
|
@@ -129,6 +189,7 @@ async function collectInteractive(options) {
|
|
|
129
189
|
tokenSymbol: tokenSymbol.trim(),
|
|
130
190
|
imageUrl: imageUrl.trim(),
|
|
131
191
|
chain,
|
|
192
|
+
quoteToken,
|
|
132
193
|
tweetUrl: tweetUrl.trim(),
|
|
133
194
|
websiteUrl: websiteUrl.trim(),
|
|
134
195
|
feeRecipient: feeRecipient.trim(),
|
|
@@ -142,8 +203,7 @@ export async function launchCommand(options) {
|
|
|
142
203
|
// Collect token details
|
|
143
204
|
const state = await collectInteractive(options);
|
|
144
205
|
if (!state.tokenName) {
|
|
145
|
-
output.
|
|
146
|
-
process.exit(1);
|
|
206
|
+
output.fatal("Token name is required.");
|
|
147
207
|
}
|
|
148
208
|
// Display summary
|
|
149
209
|
console.log();
|
|
@@ -157,17 +217,32 @@ export async function launchCommand(options) {
|
|
|
157
217
|
output.keyValue("Fee recipient", state.feeRecipient
|
|
158
218
|
? `${state.feeRecipient} (${feeTypeLabel(state.feeRecipientType)})`
|
|
159
219
|
: "(self)");
|
|
160
|
-
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)");
|
|
161
225
|
output.keyValue("Vesting", state.disableVesting
|
|
162
226
|
? "Off (100% of supply sold into the pool)"
|
|
163
227
|
: "15% to fee recipient over 1 year (default)");
|
|
164
228
|
output.keyValue("Fee collection", state.quoteOnlyFees
|
|
165
|
-
?
|
|
229
|
+
? `Quote token only (${quoteSymbol})`
|
|
166
230
|
: "Both tokens (default)");
|
|
167
231
|
if (options.simulate) {
|
|
168
232
|
output.keyValue("Mode", "Simulation (dry run)");
|
|
169
233
|
}
|
|
170
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
|
+
}
|
|
171
246
|
if (!options.yes && !output.isNonInteractive()) {
|
|
172
247
|
const proceed = await confirm({
|
|
173
248
|
message: options.simulate
|
|
@@ -198,6 +273,8 @@ export async function launchCommand(options) {
|
|
|
198
273
|
simulateOnly: options.simulate,
|
|
199
274
|
disableVesting: state.disableVesting || undefined,
|
|
200
275
|
quoteOnlyFees: state.quoteOnlyFees || undefined,
|
|
276
|
+
...(state.quoteToken &&
|
|
277
|
+
quoteTokenDeployFields(state.quoteToken.option, state.quoteToken.provider)),
|
|
201
278
|
});
|
|
202
279
|
const elapsed = output.formatDuration(Date.now() - startTime);
|
|
203
280
|
spin.succeed(result.simulated
|
|
@@ -229,8 +306,7 @@ export async function launchCommand(options) {
|
|
|
229
306
|
catch (err) {
|
|
230
307
|
spin.fail("Token launch failed");
|
|
231
308
|
emitCESP("task.error");
|
|
232
|
-
output.
|
|
233
|
-
process.exit(1);
|
|
309
|
+
output.fatal(getErrorMessage(err));
|
|
234
310
|
}
|
|
235
311
|
}
|
|
236
312
|
//# sourceMappingURL=launch.js.map
|
|
@@ -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.d.ts
CHANGED
|
@@ -23,6 +23,14 @@ export declare function setupOpenCodeCommand(opts: {
|
|
|
23
23
|
}): Promise<void>;
|
|
24
24
|
export declare function setupCursorCommand(): Promise<void>;
|
|
25
25
|
export declare function setupClaudeCodeCommand(): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Rewrite gateway-canonical Claude IDs (dotted, e.g. `claude-opus-4.8`) to
|
|
28
|
+
* the wire format Claude Code expects (dashed, e.g. `claude-opus-4-8`).
|
|
29
|
+
* Otherwise Claude Code silently falls back to its default model — the
|
|
30
|
+
* `--model` flag appears honored but the real request is a different
|
|
31
|
+
* model. Any suffix (e.g. `[1m]` context tier) is preserved.
|
|
32
|
+
*/
|
|
33
|
+
export declare function toAnthropicModelId(model: string): string;
|
|
26
34
|
export declare function claudeCommand(args: string[]): Promise<void>;
|
|
27
35
|
export declare function opencodeCommand(args: string[]): Promise<void>;
|
|
28
36
|
//# sourceMappingURL=llm.d.ts.map
|