@bankr/cli 0.3.13 → 0.3.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -10
- package/dist/cli.js +28 -7
- package/dist/commands/balances.js +2 -1
- package/dist/commands/cancel.js +2 -1
- package/dist/commands/fees.js +65 -40
- package/dist/commands/launch.d.ts +4 -0
- package/dist/commands/launch.js +42 -5
- package/dist/commands/llm.d.ts +2 -0
- package/dist/commands/llm.js +245 -43
- package/dist/commands/login.d.ts +14 -0
- package/dist/commands/login.js +41 -30
- package/dist/commands/portfolio.js +3 -2
- package/dist/commands/profile.js +6 -5
- package/dist/commands/prompt.js +19 -6
- package/dist/commands/sign.js +2 -1
- package/dist/commands/sounds.js +4 -3
- package/dist/commands/status.js +3 -2
- package/dist/commands/submit.js +3 -2
- package/dist/commands/swap.js +9 -7
- package/dist/commands/tokens.js +3 -2
- package/dist/commands/transfer.js +8 -6
- package/dist/commands/update.js +2 -1
- package/dist/commands/webhooks.js +6 -2
- package/dist/commands/whoami.js +3 -2
- package/dist/commands/x402.d.ts +3 -0
- package/dist/commands/x402.js +63 -19
- package/dist/lib/api.d.ts +13 -1
- package/dist/lib/api.js +32 -41
- package/dist/lib/output.d.ts +1 -0
- package/dist/lib/output.js +6 -0
- package/dist/lib/passthrough.d.ts +21 -0
- package/dist/lib/passthrough.js +26 -0
- package/dist/lib/tokens.d.ts +0 -5
- package/dist/lib/tokens.js +0 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -108,26 +108,44 @@ bankr agent cancel job_ABC123DEF456
|
|
|
108
108
|
Launch Claude Code / OpenCode routed through the Bankr gateway:
|
|
109
109
|
|
|
110
110
|
```bash
|
|
111
|
-
# Claude Code
|
|
112
|
-
|
|
111
|
+
# Claude Code — `bankr claude` is a top-level alias for `bankr llm claude`
|
|
112
|
+
# (auto-translates dotted model IDs to the Anthropic wire format)
|
|
113
|
+
bankr claude --model claude-opus-5
|
|
113
114
|
|
|
114
|
-
# Or use dotted form — bankr
|
|
115
|
-
bankr
|
|
115
|
+
# Or use dotted form — bankr claude rewrites it to claude-opus-4-8
|
|
116
|
+
bankr claude --model claude-opus-4.8
|
|
117
|
+
|
|
118
|
+
# The [1m] suffix is optional via the gateway, but MUST be quoted if used
|
|
119
|
+
# (zsh reads [1m] as a glob)
|
|
120
|
+
bankr claude --model "claude-opus-5[1m]"
|
|
116
121
|
|
|
117
122
|
# OpenCode (use the bankr/ prefix with the gateway-canonical dotted form)
|
|
118
123
|
bankr llm opencode -m bankr/claude-opus-4.8
|
|
119
124
|
```
|
|
120
125
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
`
|
|
124
|
-
|
|
125
|
-
|
|
126
|
+
Because `claude` is a command, it shadows the default prompt fallthrough:
|
|
127
|
+
`bankr claude ...` launches Claude Code rather than prompting the agent. Use
|
|
128
|
+
`bankr agent "..."` to send the agent a prompt starting with that word.
|
|
129
|
+
|
|
130
|
+
**Claude Code model format**: Claude Code's `--model` flag expects Anthropic
|
|
131
|
+
wire IDs, which use dashes rather than dots in the version (`claude-opus-5`,
|
|
132
|
+
`claude-sonnet-5`, `claude-opus-4-8`, `claude-haiku-4-5`). If you pass the
|
|
133
|
+
gateway-canonical dotted form (`claude-opus-4.8`), Claude Code silently falls
|
|
134
|
+
back to its default — the flag appears honored but the real request is a
|
|
135
|
+
different model.
|
|
126
136
|
|
|
127
|
-
`bankr
|
|
137
|
+
`bankr claude` translates dotted → dashed for you. If you use older
|
|
128
138
|
versions of the CLI (or invoke `claude` directly via `ANTHROPIC_BASE_URL`),
|
|
129
139
|
pass the dashed form explicitly.
|
|
130
140
|
|
|
141
|
+
**1M context tier**: the gateway strips Claude Code's `[1m]` suffix and enables
|
|
142
|
+
the 1M beta from the model's own context window, so it's **optional here** —
|
|
143
|
+
`claude-opus-5` and `claude-opus-5[1m]` send an identical upstream request. If
|
|
144
|
+
you do use it, **quote it**: in zsh (the macOS default) `[1m]` is a glob
|
|
145
|
+
character class, so an unquoted id aborts with `zsh: no matches found:
|
|
146
|
+
claude-opus-5[1m]` before the CLI ever runs. Bash passes it through literally,
|
|
147
|
+
so the same command can work on one machine and fail on another.
|
|
148
|
+
|
|
131
149
|
### Configuration
|
|
132
150
|
|
|
133
151
|
```bash
|
package/dist/cli.js
CHANGED
|
@@ -10,6 +10,8 @@ import { skillsCommand } from "./commands/capabilities.js";
|
|
|
10
10
|
import { cancelCommand } from "./commands/cancel.js";
|
|
11
11
|
import { configGetCommand, configSetCommand } from "./commands/config.js";
|
|
12
12
|
import { setConfigPath } from "./lib/config.js";
|
|
13
|
+
import { getErrorMessage } from "./lib/errors.js";
|
|
14
|
+
import { passthroughArgs } from "./lib/passthrough.js";
|
|
13
15
|
import { claudeCommand, creditsCommand, creditsAddCommand, creditsAutoCommand, modelsCommand, opencodeCommand, setupClaudeCodeCommand, setupCursorCommand, setupOpenclawCommand, setupOpenCodeCommand, } from "./commands/llm.js";
|
|
14
16
|
import { feesCommand, feesClaimCommand, feesClaimWalletCommand, } from "./commands/fees.js";
|
|
15
17
|
import { launchCommand } from "./commands/launch.js";
|
|
@@ -346,12 +348,14 @@ program
|
|
|
346
348
|
.option("--symbol <symbol>", "Token symbol (default: auto-generated from name)")
|
|
347
349
|
.option("--image <url>", "Token image URL")
|
|
348
350
|
.option("--chain <chain>", "Chain to launch on: base, robinhood (default: base)")
|
|
351
|
+
.option("--no-vesting", "Turn off the default 15% creator vesting (sell 100% of supply into the pool)")
|
|
349
352
|
.optionsGroup("Links")
|
|
350
353
|
.option("--tweet <url>", "Associated tweet URL")
|
|
351
354
|
.option("--website <url>", "Project website URL")
|
|
352
355
|
.optionsGroup("Fees")
|
|
353
356
|
.option("--fee <recipient>", "Fee recipient (username, ENS, or address)")
|
|
354
357
|
.option("--fee-type <type>", "Fee recipient type: x, farcaster, ens, wallet (default: x)")
|
|
358
|
+
.option("--quote-only-fees", "Collect all creator fees in the pool's quote token (e.g. WETH) instead of a mix of your token and the quote token")
|
|
355
359
|
.optionsGroup("")
|
|
356
360
|
.option("-y, --yes", "Skip confirmation prompt")
|
|
357
361
|
.option("--simulate", "Simulate the deploy without broadcasting a transaction")
|
|
@@ -361,10 +365,12 @@ program
|
|
|
361
365
|
symbol: opts.symbol,
|
|
362
366
|
image: opts.image,
|
|
363
367
|
chain: opts.chain,
|
|
368
|
+
vesting: opts.vesting,
|
|
364
369
|
tweet: opts.tweet,
|
|
365
370
|
website: opts.website,
|
|
366
371
|
fee: opts.fee,
|
|
367
372
|
feeType: opts.feeType,
|
|
373
|
+
quoteOnlyFees: opts.quoteOnlyFees,
|
|
368
374
|
yes: opts.yes,
|
|
369
375
|
simulate: opts.simulate,
|
|
370
376
|
});
|
|
@@ -471,6 +477,7 @@ llmCmd
|
|
|
471
477
|
.command("models")
|
|
472
478
|
.description("List available models")
|
|
473
479
|
.option("--private", "Show only models that support private (:private) inference")
|
|
480
|
+
.option("--zdr", "Show only models that support zero data retention (:zdr)")
|
|
474
481
|
.action(modelsCommand);
|
|
475
482
|
const llmCreditsCmd = llmCmd
|
|
476
483
|
.command("credits")
|
|
@@ -498,6 +505,7 @@ llmSetupCmd
|
|
|
498
505
|
.command("openclaw")
|
|
499
506
|
.description("OpenClaw config")
|
|
500
507
|
.option("--install", "Write config to ~/.openclaw/openclaw.json")
|
|
508
|
+
.option("--images", "Also route image generation (gpt-image-2) through the gateway — takes over OpenClaw's 'openai' provider slot")
|
|
501
509
|
.action(setupOpenclawCommand);
|
|
502
510
|
llmSetupCmd
|
|
503
511
|
.command("opencode")
|
|
@@ -512,25 +520,38 @@ llmSetupCmd
|
|
|
512
520
|
.command("claude")
|
|
513
521
|
.description("Claude Code config")
|
|
514
522
|
.action(setupClaudeCodeCommand);
|
|
523
|
+
// `helpOption(false)` forwards `-h`/`--help` to the spawned tool instead of
|
|
524
|
+
// letting commander print ours — on a pure passthrough launcher the user
|
|
525
|
+
// almost always wants the tool's help. Use `bankr llm --help` for ours.
|
|
515
526
|
llmCmd
|
|
516
527
|
.command("claude")
|
|
517
528
|
.description("Run Claude Code via gateway")
|
|
518
529
|
.allowUnknownOption()
|
|
519
530
|
.allowExcessArguments()
|
|
531
|
+
.helpOption(false)
|
|
520
532
|
.action(async () => {
|
|
521
|
-
|
|
522
|
-
const args = idx >= 0 ? process.argv.slice(idx + 1) : [];
|
|
523
|
-
await claudeCommand(args);
|
|
533
|
+
await claudeCommand(passthroughArgs("claude"));
|
|
524
534
|
});
|
|
525
535
|
llmCmd
|
|
526
536
|
.command("opencode")
|
|
527
537
|
.description("Run OpenCode via gateway")
|
|
528
538
|
.allowUnknownOption()
|
|
529
539
|
.allowExcessArguments()
|
|
540
|
+
.helpOption(false)
|
|
530
541
|
.action(async () => {
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
542
|
+
await opencodeCommand(passthroughArgs("opencode"));
|
|
543
|
+
});
|
|
544
|
+
// Top-level shorthand for the most-used launcher. This shadows the default
|
|
545
|
+
// prompt fallthrough, so `bankr claude ...` launches Claude Code rather than
|
|
546
|
+
// prompting the agent about Claude — ask the agent via `bankr agent "..."`.
|
|
547
|
+
program
|
|
548
|
+
.command("claude")
|
|
549
|
+
.description("Run Claude Code via gateway (alias for `bankr llm claude`)")
|
|
550
|
+
.allowUnknownOption()
|
|
551
|
+
.allowExcessArguments()
|
|
552
|
+
.helpOption(false)
|
|
553
|
+
.action(async () => {
|
|
554
|
+
await claudeCommand(passthroughArgs("claude"));
|
|
534
555
|
});
|
|
535
556
|
// Token search and info
|
|
536
557
|
program.commandsGroup("Tokens");
|
|
@@ -1048,7 +1069,7 @@ async function main() {
|
|
|
1048
1069
|
console.log();
|
|
1049
1070
|
process.exit(0);
|
|
1050
1071
|
}
|
|
1051
|
-
output.error(err
|
|
1072
|
+
output.error(getErrorMessage(err));
|
|
1052
1073
|
process.exit(1);
|
|
1053
1074
|
}
|
|
1054
1075
|
await checkForUpdate(pkg.version);
|
|
@@ -2,6 +2,7 @@ import chalk from "chalk";
|
|
|
2
2
|
import { getBalances, } from "../lib/api.js";
|
|
3
3
|
import * as output from "../lib/output.js";
|
|
4
4
|
import { formatUsd, formatBalance } from "../lib/output.js";
|
|
5
|
+
import { getErrorMessage } from "../lib/errors.js";
|
|
5
6
|
import { CHAIN_LABELS, VALID_CHAINS } from "../lib/chains.js";
|
|
6
7
|
const BRAND = chalk.hex("#FF613D");
|
|
7
8
|
const DIM = chalk.dim;
|
|
@@ -53,7 +54,7 @@ export async function balancesCommand(opts) {
|
|
|
53
54
|
spin.succeed("Balances loaded");
|
|
54
55
|
}
|
|
55
56
|
catch (err) {
|
|
56
|
-
spin.fail(`Failed to fetch balances: ${err
|
|
57
|
+
spin.fail(`Failed to fetch balances: ${getErrorMessage(err)}`);
|
|
57
58
|
process.exit(1);
|
|
58
59
|
}
|
|
59
60
|
// JSON output mode
|
package/dist/commands/cancel.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { cancelJob } from "../lib/api.js";
|
|
2
2
|
import { requireApiKey } from "../lib/config.js";
|
|
3
3
|
import * as output from "../lib/output.js";
|
|
4
|
+
import { getErrorMessage } from "../lib/errors.js";
|
|
4
5
|
export async function cancelCommand(jobId) {
|
|
5
6
|
requireApiKey();
|
|
6
7
|
const spin = output.spinner("Cancelling job...");
|
|
@@ -18,7 +19,7 @@ export async function cancelCommand(jobId) {
|
|
|
18
19
|
}
|
|
19
20
|
catch (err) {
|
|
20
21
|
spin.fail("Failed to cancel job");
|
|
21
|
-
output.error(err
|
|
22
|
+
output.error(getErrorMessage(err));
|
|
22
23
|
process.exit(1);
|
|
23
24
|
}
|
|
24
25
|
}
|
package/dist/commands/fees.js
CHANGED
|
@@ -6,6 +6,7 @@ import { emitCESP } from "../lib/cesp/engine.js";
|
|
|
6
6
|
import { requireApiKey } from "../lib/config.js";
|
|
7
7
|
import { txExplorer } from "../lib/explorer.js";
|
|
8
8
|
import * as output from "../lib/output.js";
|
|
9
|
+
import { getErrorMessage } from "../lib/errors.js";
|
|
9
10
|
// ---------------------------------------------------------------------------
|
|
10
11
|
// Constants
|
|
11
12
|
// ---------------------------------------------------------------------------
|
|
@@ -283,28 +284,33 @@ function renderDashboard(data) {
|
|
|
283
284
|
console.log(` ${BRAND_BOLD("\u2550".repeat(62))}`);
|
|
284
285
|
console.log("");
|
|
285
286
|
for (const token of data.tokens) {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
287
|
+
// Numeraire leg = the side whose label differs from the launched token's
|
|
288
|
+
// symbol \u2014 stock-paired launches label it with the stock ticker, not WETH.
|
|
289
|
+
const tokenIsToken0 = token.token0Label === token.symbol;
|
|
290
|
+
const numeraireLabel = tokenIsToken0
|
|
291
|
+
? token.token1Label
|
|
292
|
+
: token.token0Label;
|
|
293
|
+
const claimableNumeraire = tokenIsToken0
|
|
291
294
|
? token.claimable.token1
|
|
292
295
|
: token.claimable.token0;
|
|
293
|
-
const
|
|
294
|
-
? token.
|
|
295
|
-
: token.
|
|
296
|
-
const
|
|
296
|
+
const claimableToken = tokenIsToken0
|
|
297
|
+
? token.claimable.token0
|
|
298
|
+
: token.claimable.token1;
|
|
299
|
+
const claimedNumeraire = tokenIsToken0
|
|
297
300
|
? token.claimed.token1
|
|
298
301
|
: token.claimed.token0;
|
|
299
|
-
const
|
|
302
|
+
const claimedToken = tokenIsToken0
|
|
303
|
+
? token.claimed.token0
|
|
304
|
+
: token.claimed.token1;
|
|
305
|
+
const tokenSymbol = tokenIsToken0 ? token.token0Label : token.token1Label;
|
|
300
306
|
const sourceLabel = token.source === "clanker" ? DIM(" [Clanker]") : DIM(" [Doppler]");
|
|
301
307
|
console.log(` ${BOLD(WHITE(token.name))} ${DIM("($" + token.symbol + ")")}${sourceLabel}`);
|
|
302
308
|
const shareInfo = token.source === "clanker"
|
|
303
309
|
? `${DIM("Creator")} ${DIM("\u00b7 Token:")} ${DIM(token.tokenAddress)}`
|
|
304
310
|
: `${DIM("Share:")} ${token.share} ${DIM("\u00b7 Token:")} ${DIM(token.tokenAddress)}`;
|
|
305
311
|
console.log(` ${shareInfo}`);
|
|
306
|
-
console.log(` ${DIM("Claimable:")} ${BRIGHT_GREEN(
|
|
307
|
-
console.log(` ${DIM("Claimed:")} ${WHITE(
|
|
312
|
+
console.log(` ${DIM("Claimable:")} ${BRIGHT_GREEN(claimableNumeraire.padStart(12))} ${numeraireLabel} ${DIM("|")} ${BRIGHT_GREEN(claimableToken.padStart(18))} ${tokenSymbol}`);
|
|
313
|
+
console.log(` ${DIM("Claimed:")} ${WHITE(claimedNumeraire.padStart(12))} ${numeraireLabel} ${DIM("|")} ${WHITE(claimedToken.padStart(18))} ${tokenSymbol} ${DIM(`(${token.claimed.count} claims)`)}`);
|
|
308
314
|
console.log("");
|
|
309
315
|
}
|
|
310
316
|
console.log(` ${BRAND_BOLD("\u2550".repeat(62))}`);
|
|
@@ -343,7 +349,7 @@ export async function feesCommand(address, opts) {
|
|
|
343
349
|
catch (err) {
|
|
344
350
|
spin.fail("Failed to fetch token fee data");
|
|
345
351
|
emitCESP("task.error");
|
|
346
|
-
output.error(err
|
|
352
|
+
output.error(getErrorMessage(err));
|
|
347
353
|
process.exit(1);
|
|
348
354
|
}
|
|
349
355
|
return;
|
|
@@ -365,7 +371,7 @@ export async function feesCommand(address, opts) {
|
|
|
365
371
|
}
|
|
366
372
|
catch (err) {
|
|
367
373
|
spin.fail("Failed to fetch wallet info");
|
|
368
|
-
output.error(err
|
|
374
|
+
output.error(getErrorMessage(err));
|
|
369
375
|
process.exit(1);
|
|
370
376
|
}
|
|
371
377
|
}
|
|
@@ -384,7 +390,7 @@ export async function feesCommand(address, opts) {
|
|
|
384
390
|
catch (err) {
|
|
385
391
|
spin.fail("Failed to fetch fee data");
|
|
386
392
|
emitCESP("task.error");
|
|
387
|
-
output.error(err
|
|
393
|
+
output.error(getErrorMessage(err));
|
|
388
394
|
process.exit(1);
|
|
389
395
|
}
|
|
390
396
|
}
|
|
@@ -445,7 +451,7 @@ export async function feesClaimCommand(tokenAddress, opts) {
|
|
|
445
451
|
catch (err) {
|
|
446
452
|
spin.fail("Claim submission failed");
|
|
447
453
|
emitCESP("task.error");
|
|
448
|
-
output.error(err
|
|
454
|
+
output.error(getErrorMessage(err));
|
|
449
455
|
process.exit(1);
|
|
450
456
|
}
|
|
451
457
|
}
|
|
@@ -550,42 +556,64 @@ export async function feesClaimWalletCommand(address, opts) {
|
|
|
550
556
|
const result = await getBeneficiaryFeesStreaming(address, (progress) => {
|
|
551
557
|
fetchSpin.text = `Scanning pools... ${progress.scanned}/${progress.total} (${progress.found ?? 0} with claimable fees)`;
|
|
552
558
|
});
|
|
553
|
-
|
|
559
|
+
// A time-budget stop leaves `scanned` below `totalLaunches`; report the
|
|
560
|
+
// number actually scanned so this line can't contradict the warning below.
|
|
561
|
+
const scanned = result.scanned ?? result.totalLaunches;
|
|
562
|
+
fetchSpin.succeed(`Scanned ${scanned} launches — ${result.poolsWithShares} pools with shares, ${result.tokens.length} with claimable fees`);
|
|
563
|
+
if (result.truncated) {
|
|
564
|
+
output.warn(`Scan stopped early at ${scanned} launches — this wallet has more than the server scans in one request. Claimable fees beyond that are not listed.`);
|
|
565
|
+
}
|
|
554
566
|
allTokens = result.tokens;
|
|
555
567
|
}
|
|
556
568
|
catch (err) {
|
|
557
569
|
fetchSpin.fail("Failed to fetch fee data");
|
|
558
|
-
output.error(err
|
|
570
|
+
output.error(getErrorMessage(err));
|
|
559
571
|
process.exit(1);
|
|
560
572
|
}
|
|
561
573
|
// Step 5: Filter to tokens with claimable fees (API already filters, but
|
|
562
574
|
// double-check for any rounding edge cases)
|
|
563
575
|
const parseAmount = (s) => parseFloat(s.replace(/^[<>]/, "")) || 0;
|
|
576
|
+
// Numeraire leg = the side whose label differs from the launched token's
|
|
577
|
+
// symbol — stock-paired launches label it with the stock ticker, not WETH.
|
|
578
|
+
const numeraireLegOf = (token) => {
|
|
579
|
+
const tokenIsToken0 = token.token0Label === token.symbol;
|
|
580
|
+
return {
|
|
581
|
+
label: tokenIsToken0 ? token.token1Label : token.token0Label,
|
|
582
|
+
claimable: tokenIsToken0
|
|
583
|
+
? token.claimable.token1
|
|
584
|
+
: token.claimable.token0,
|
|
585
|
+
tokenClaimable: tokenIsToken0
|
|
586
|
+
? token.claimable.token0
|
|
587
|
+
: token.claimable.token1,
|
|
588
|
+
};
|
|
589
|
+
};
|
|
564
590
|
const claimableTokens = allTokens.filter((token) => {
|
|
565
|
-
const
|
|
566
|
-
|
|
567
|
-
? token.claimable.token0
|
|
568
|
-
: token.claimable.token1;
|
|
569
|
-
const claimableToken = wethIsToken0
|
|
570
|
-
? token.claimable.token1
|
|
571
|
-
: token.claimable.token0;
|
|
572
|
-
return parseAmount(claimableWeth) > 0 || parseAmount(claimableToken) > 0;
|
|
591
|
+
const leg = numeraireLegOf(token);
|
|
592
|
+
return (parseAmount(leg.claimable) > 0 || parseAmount(leg.tokenClaimable) > 0);
|
|
573
593
|
});
|
|
574
594
|
if (claimableTokens.length === 0) {
|
|
575
595
|
console.log();
|
|
576
596
|
output.dim("No claimable fees found for this wallet.");
|
|
577
597
|
return;
|
|
578
598
|
}
|
|
579
|
-
// Show total claimable WETH
|
|
599
|
+
// Show total claimable WETH — WETH legs only; stock-paired numeraires are a
|
|
600
|
+
// different unit and get their own per-ticker lines.
|
|
580
601
|
const totalWeth = claimableTokens.reduce((sum, token) => {
|
|
581
|
-
const
|
|
582
|
-
|
|
583
|
-
? token.claimable.token0
|
|
584
|
-
: token.claimable.token1;
|
|
585
|
-
return sum + parseAmount(wethStr);
|
|
602
|
+
const leg = numeraireLegOf(token);
|
|
603
|
+
return leg.label === "WETH" ? sum + parseAmount(leg.claimable) : sum;
|
|
586
604
|
}, 0);
|
|
605
|
+
const nonWethTotals = new Map();
|
|
606
|
+
for (const token of claimableTokens) {
|
|
607
|
+
const leg = numeraireLegOf(token);
|
|
608
|
+
if (leg.label !== "WETH" && parseAmount(leg.claimable) > 0) {
|
|
609
|
+
nonWethTotals.set(leg.label, (nonWethTotals.get(leg.label) ?? 0) + parseAmount(leg.claimable));
|
|
610
|
+
}
|
|
611
|
+
}
|
|
587
612
|
console.log();
|
|
588
613
|
output.keyValue("Total claimable", `${totalWeth.toFixed(6)} WETH across ${claimableTokens.length} token${claimableTokens.length !== 1 ? "s" : ""}`);
|
|
614
|
+
for (const [label, amount] of nonWethTotals) {
|
|
615
|
+
output.keyValue("", `${amount.toFixed(6)} ${label} (stock-paired)`);
|
|
616
|
+
}
|
|
589
617
|
// Step 6: Select tokens
|
|
590
618
|
let selectedTokens;
|
|
591
619
|
if (opts.all) {
|
|
@@ -593,12 +621,9 @@ export async function feesClaimWalletCommand(address, opts) {
|
|
|
593
621
|
}
|
|
594
622
|
else {
|
|
595
623
|
const choices = claimableTokens.map((token) => {
|
|
596
|
-
const
|
|
597
|
-
const claimableWeth = wethIsToken0
|
|
598
|
-
? token.claimable.token0
|
|
599
|
-
: token.claimable.token1;
|
|
624
|
+
const leg = numeraireLegOf(token);
|
|
600
625
|
return {
|
|
601
|
-
name: `${token.name} ($${token.symbol}) - ${
|
|
626
|
+
name: `${token.name} ($${token.symbol}) - ${leg.claimable} ${leg.label}`,
|
|
602
627
|
value: token.tokenAddress,
|
|
603
628
|
checked: true,
|
|
604
629
|
};
|
|
@@ -676,7 +701,7 @@ export async function feesClaimWalletCommand(address, opts) {
|
|
|
676
701
|
return (gas * GAS_BUFFER) / 100n;
|
|
677
702
|
}
|
|
678
703
|
catch (err) {
|
|
679
|
-
output.warn(`${token.symbol}: gas estimate failed — ${err
|
|
704
|
+
output.warn(`${token.symbol}: gas estimate failed — ${getErrorMessage(err)}`);
|
|
680
705
|
return null;
|
|
681
706
|
}
|
|
682
707
|
}));
|
|
@@ -737,7 +762,7 @@ export async function feesClaimWalletCommand(address, opts) {
|
|
|
737
762
|
pendingTxs.push({ token: tx.token, hash });
|
|
738
763
|
}
|
|
739
764
|
catch (err) {
|
|
740
|
-
sendSpin.fail(`${tx.token.symbol}: Send failed — ${err
|
|
765
|
+
sendSpin.fail(`${tx.token.symbol}: Send failed — ${getErrorMessage(err)}`);
|
|
741
766
|
emitCESP("task.error");
|
|
742
767
|
failCount++;
|
|
743
768
|
if (readyTxs.indexOf(tx) < readyTxs.length - 1) {
|
|
@@ -767,7 +792,7 @@ export async function feesClaimWalletCommand(address, opts) {
|
|
|
767
792
|
token,
|
|
768
793
|
hash,
|
|
769
794
|
status: "failed",
|
|
770
|
-
error: err
|
|
795
|
+
error: getErrorMessage(err),
|
|
771
796
|
};
|
|
772
797
|
}
|
|
773
798
|
}));
|
|
@@ -3,10 +3,14 @@ export interface LaunchOptions {
|
|
|
3
3
|
symbol?: string;
|
|
4
4
|
image?: string;
|
|
5
5
|
chain?: string;
|
|
6
|
+
/** Commander --no-vesting flag: false = vesting explicitly turned off. */
|
|
7
|
+
vesting?: boolean;
|
|
6
8
|
tweet?: string;
|
|
7
9
|
website?: string;
|
|
8
10
|
fee?: string;
|
|
9
11
|
feeType?: string;
|
|
12
|
+
/** --quote-only-fees flag: collect all creator fees in the quote token. */
|
|
13
|
+
quoteOnlyFees?: boolean;
|
|
10
14
|
yes?: boolean;
|
|
11
15
|
simulate?: boolean;
|
|
12
16
|
}
|
package/dist/commands/launch.js
CHANGED
|
@@ -3,6 +3,7 @@ import { deployToken, } 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
|
+
import { getErrorMessage } from "../lib/errors.js";
|
|
6
7
|
const VALID_FEE_TYPES = ["x", "farcaster", "ens", "wallet"];
|
|
7
8
|
const VALID_CHAINS = ["base", "robinhood"];
|
|
8
9
|
function chainLabel(chain) {
|
|
@@ -75,6 +76,34 @@ async function collectInteractive(options) {
|
|
|
75
76
|
});
|
|
76
77
|
}
|
|
77
78
|
chain ?? (chain = "base");
|
|
79
|
+
// Vesting: --no-vesting wins; otherwise interactive select (default: keep
|
|
80
|
+
// the 15% creator vesting). Non-interactive runs keep vesting on.
|
|
81
|
+
let disableVesting = options.vesting === false;
|
|
82
|
+
if (!disableVesting && !output.isNonInteractive()) {
|
|
83
|
+
disableVesting = await select({
|
|
84
|
+
message: "Creator vesting? By default 15% of supply vests to the fee recipient over 1 year (30-day cliff).",
|
|
85
|
+
choices: [
|
|
86
|
+
{ name: "15% vesting (default)", value: false },
|
|
87
|
+
{ name: "No vesting — sell 100% into the pool", value: true },
|
|
88
|
+
],
|
|
89
|
+
default: false,
|
|
90
|
+
theme: output.bankrTheme,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
// Fee collection: --quote-only-fees wins; otherwise interactive select
|
|
94
|
+
// (default: in-kind). Non-interactive runs keep the in-kind default.
|
|
95
|
+
let quoteOnlyFees = options.quoteOnlyFees === true;
|
|
96
|
+
if (!quoteOnlyFees && !output.isNonInteractive()) {
|
|
97
|
+
quoteOnlyFees = await select({
|
|
98
|
+
message: "Fee collection? By default creator fees accrue as a mix of your token and the pool's quote token (e.g. WETH).",
|
|
99
|
+
choices: [
|
|
100
|
+
{ name: "Both tokens (default)", value: false },
|
|
101
|
+
{ name: "Quote token only", value: true },
|
|
102
|
+
],
|
|
103
|
+
default: false,
|
|
104
|
+
theme: output.bankrTheme,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
78
107
|
const tweetUrl = options.tweet ??
|
|
79
108
|
(await promptOrSkip("Associate with a tweet? Paste URL (press Enter to skip):"));
|
|
80
109
|
const websiteUrl = options.website ??
|
|
@@ -94,9 +123,7 @@ async function collectInteractive(options) {
|
|
|
94
123
|
theme: output.bankrTheme,
|
|
95
124
|
});
|
|
96
125
|
}
|
|
97
|
-
|
|
98
|
-
feeRecipient = "";
|
|
99
|
-
}
|
|
126
|
+
feeRecipient || (feeRecipient = "");
|
|
100
127
|
return {
|
|
101
128
|
tokenName: tokenName.trim(),
|
|
102
129
|
tokenSymbol: tokenSymbol.trim(),
|
|
@@ -106,6 +133,8 @@ async function collectInteractive(options) {
|
|
|
106
133
|
websiteUrl: websiteUrl.trim(),
|
|
107
134
|
feeRecipient: feeRecipient.trim(),
|
|
108
135
|
feeRecipientType,
|
|
136
|
+
disableVesting,
|
|
137
|
+
quoteOnlyFees,
|
|
109
138
|
};
|
|
110
139
|
}
|
|
111
140
|
export async function launchCommand(options) {
|
|
@@ -129,6 +158,12 @@ export async function launchCommand(options) {
|
|
|
129
158
|
? `${state.feeRecipient} (${feeTypeLabel(state.feeRecipientType)})`
|
|
130
159
|
: "(self)");
|
|
131
160
|
output.keyValue("Chain", chainLabel(state.chain));
|
|
161
|
+
output.keyValue("Vesting", state.disableVesting
|
|
162
|
+
? "Off (100% of supply sold into the pool)"
|
|
163
|
+
: "15% to fee recipient over 1 year (default)");
|
|
164
|
+
output.keyValue("Fee collection", state.quoteOnlyFees
|
|
165
|
+
? "Quote token only (e.g. WETH)"
|
|
166
|
+
: "Both tokens (default)");
|
|
132
167
|
if (options.simulate) {
|
|
133
168
|
output.keyValue("Mode", "Simulation (dry run)");
|
|
134
169
|
}
|
|
@@ -161,6 +196,8 @@ export async function launchCommand(options) {
|
|
|
161
196
|
? { type: state.feeRecipientType, value: state.feeRecipient }
|
|
162
197
|
: undefined,
|
|
163
198
|
simulateOnly: options.simulate,
|
|
199
|
+
disableVesting: state.disableVesting || undefined,
|
|
200
|
+
quoteOnlyFees: state.quoteOnlyFees || undefined,
|
|
164
201
|
});
|
|
165
202
|
const elapsed = output.formatDuration(Date.now() - startTime);
|
|
166
203
|
spin.succeed(result.simulated
|
|
@@ -187,12 +224,12 @@ export async function launchCommand(options) {
|
|
|
187
224
|
}
|
|
188
225
|
}
|
|
189
226
|
console.log();
|
|
190
|
-
output.dim(`View token: https://bankr.bot/
|
|
227
|
+
output.dim(`View token: https://bankr.bot/terminal/trade?out=${result.tokenAddress}&chain=${result.chain}`);
|
|
191
228
|
}
|
|
192
229
|
catch (err) {
|
|
193
230
|
spin.fail("Token launch failed");
|
|
194
231
|
emitCESP("task.error");
|
|
195
|
-
output.error(err
|
|
232
|
+
output.error(getErrorMessage(err));
|
|
196
233
|
process.exit(1);
|
|
197
234
|
}
|
|
198
235
|
}
|
package/dist/commands/llm.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare function modelsCommand(opts?: {
|
|
2
2
|
private?: boolean;
|
|
3
|
+
zdr?: boolean;
|
|
3
4
|
}): Promise<void>;
|
|
4
5
|
export declare function creditsCommand(): Promise<void>;
|
|
5
6
|
export declare function creditsAddCommand(amount: string, opts: {
|
|
@@ -15,6 +16,7 @@ export declare function creditsAutoCommand(opts: {
|
|
|
15
16
|
}): Promise<void>;
|
|
16
17
|
export declare function setupOpenclawCommand(opts: {
|
|
17
18
|
install?: boolean;
|
|
19
|
+
images?: boolean;
|
|
18
20
|
}): Promise<void>;
|
|
19
21
|
export declare function setupOpenCodeCommand(opts: {
|
|
20
22
|
install?: boolean;
|