@bankr/cli 0.3.13 → 0.3.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -10
- package/dist/cli.js +34 -18
- package/dist/commands/balances.js +3 -3
- package/dist/commands/cancel.js +1 -3
- package/dist/commands/club.js +6 -16
- package/dist/commands/config.js +1 -2
- package/dist/commands/fees.js +79 -64
- package/dist/commands/files.js +17 -39
- package/dist/commands/launch.d.ts +4 -0
- package/dist/commands/launch.js +56 -18
- package/dist/commands/llm.d.ts +10 -0
- package/dist/commands/llm.js +510 -99
- package/dist/commands/login.d.ts +14 -0
- package/dist/commands/login.js +57 -57
- package/dist/commands/portfolio.js +4 -4
- package/dist/commands/profile.js +6 -5
- package/dist/commands/prompt.js +36 -26
- package/dist/commands/sign.js +9 -16
- package/dist/commands/sounds.js +6 -15
- package/dist/commands/status.js +2 -4
- package/dist/commands/submit.js +13 -24
- package/dist/commands/swap.js +11 -11
- package/dist/commands/tokens.js +4 -4
- package/dist/commands/transfer.js +10 -10
- package/dist/commands/update.js +2 -2
- package/dist/commands/webhooks.js +27 -67
- package/dist/commands/whoami.js +4 -4
- package/dist/commands/x402.d.ts +3 -0
- package/dist/commands/x402.js +95 -115
- package/dist/lib/api.d.ts +17 -3
- package/dist/lib/api.js +34 -43
- package/dist/lib/explorer.js +1 -0
- package/dist/lib/output.d.ts +5 -0
- package/dist/lib/output.js +18 -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/dist/commands/status.js
CHANGED
|
@@ -31,15 +31,13 @@ export async function statusCommand(jobId) {
|
|
|
31
31
|
console.log();
|
|
32
32
|
output.error(status.error);
|
|
33
33
|
}
|
|
34
|
-
if (status.transactions
|
|
34
|
+
if (status.transactions?.length) {
|
|
35
35
|
console.log();
|
|
36
36
|
output.dim(`${status.transactions.length} transaction(s) attached.`);
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
catch (err) {
|
|
40
|
-
|
|
41
|
-
output.error(err.message);
|
|
42
|
-
process.exit(1);
|
|
40
|
+
output.failWith(spin, "Failed to fetch job status", err);
|
|
43
41
|
}
|
|
44
42
|
}
|
|
45
43
|
//# sourceMappingURL=status.js.map
|
package/dist/commands/submit.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { submit } from "../lib/api.js";
|
|
2
2
|
import { emitCESP } from "../lib/cesp/engine.js";
|
|
3
3
|
import * as output from "../lib/output.js";
|
|
4
|
+
import { getErrorMessage } from "../lib/errors.js";
|
|
4
5
|
function displayResult(result) {
|
|
5
6
|
if (!result.success) {
|
|
6
7
|
emitCESP("task.error");
|
|
@@ -27,24 +28,20 @@ function displayResult(result) {
|
|
|
27
28
|
export async function submitCommand(opts) {
|
|
28
29
|
// Validate required fields
|
|
29
30
|
if (!opts.to) {
|
|
30
|
-
output.
|
|
31
|
-
process.exit(1);
|
|
31
|
+
output.fatal("--to is required");
|
|
32
32
|
}
|
|
33
33
|
if (!opts.chainId) {
|
|
34
|
-
output.
|
|
35
|
-
process.exit(1);
|
|
34
|
+
output.fatal("--chain-id is required");
|
|
36
35
|
}
|
|
37
36
|
const chainId = parseInt(opts.chainId, 10);
|
|
38
37
|
if (isNaN(chainId)) {
|
|
39
|
-
output.
|
|
40
|
-
process.exit(1);
|
|
38
|
+
output.fatal("--chain-id must be a number");
|
|
41
39
|
}
|
|
42
40
|
let nonce;
|
|
43
41
|
if (opts.nonce) {
|
|
44
42
|
nonce = parseInt(opts.nonce, 10);
|
|
45
43
|
if (isNaN(nonce)) {
|
|
46
|
-
output.
|
|
47
|
-
process.exit(1);
|
|
44
|
+
output.fatal("--nonce must be a number");
|
|
48
45
|
}
|
|
49
46
|
}
|
|
50
47
|
const request = {
|
|
@@ -73,8 +70,7 @@ export async function submitCommand(opts) {
|
|
|
73
70
|
}
|
|
74
71
|
catch (err) {
|
|
75
72
|
spinner.stop();
|
|
76
|
-
output.
|
|
77
|
-
process.exit(1);
|
|
73
|
+
output.fatal(getErrorMessage(err));
|
|
78
74
|
}
|
|
79
75
|
}
|
|
80
76
|
// Alternative: submit from JSON
|
|
@@ -84,32 +80,26 @@ export async function submitJsonCommand(json, opts) {
|
|
|
84
80
|
transaction = JSON.parse(json);
|
|
85
81
|
}
|
|
86
82
|
catch {
|
|
87
|
-
output.
|
|
88
|
-
process.exit(1);
|
|
83
|
+
output.fatal("Invalid JSON. Expected: {to, chainId, value?, data?}");
|
|
89
84
|
}
|
|
90
85
|
if (!transaction ||
|
|
91
86
|
typeof transaction !== "object" ||
|
|
92
87
|
Array.isArray(transaction)) {
|
|
93
|
-
output.
|
|
94
|
-
process.exit(1);
|
|
88
|
+
output.fatal("Invalid JSON. Expected object: {to, chainId, value?, data?}");
|
|
95
89
|
}
|
|
96
90
|
// Validate required fields
|
|
97
91
|
if (!transaction.to) {
|
|
98
|
-
output.
|
|
99
|
-
process.exit(1);
|
|
92
|
+
output.fatal("Transaction must have 'to' field");
|
|
100
93
|
}
|
|
101
94
|
if (transaction.chainId === undefined) {
|
|
102
|
-
output.
|
|
103
|
-
process.exit(1);
|
|
95
|
+
output.fatal("Transaction must have 'chainId' field");
|
|
104
96
|
}
|
|
105
97
|
if (typeof transaction.chainId !== "number" || isNaN(transaction.chainId)) {
|
|
106
|
-
output.
|
|
107
|
-
process.exit(1);
|
|
98
|
+
output.fatal("Transaction 'chainId' must be a number");
|
|
108
99
|
}
|
|
109
100
|
if (transaction.nonce !== undefined &&
|
|
110
101
|
(typeof transaction.nonce !== "number" || isNaN(transaction.nonce))) {
|
|
111
|
-
output.
|
|
112
|
-
process.exit(1);
|
|
102
|
+
output.fatal("Transaction 'nonce' must be a number");
|
|
113
103
|
}
|
|
114
104
|
const request = {
|
|
115
105
|
transaction,
|
|
@@ -127,8 +117,7 @@ export async function submitJsonCommand(json, opts) {
|
|
|
127
117
|
}
|
|
128
118
|
catch (err) {
|
|
129
119
|
spinner.stop();
|
|
130
|
-
output.
|
|
131
|
-
process.exit(1);
|
|
120
|
+
output.fatal(getErrorMessage(err));
|
|
132
121
|
}
|
|
133
122
|
}
|
|
134
123
|
//# sourceMappingURL=submit.js.map
|
package/dist/commands/swap.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { getSwapQuote, executeSwap } from "../lib/api.js";
|
|
2
2
|
import * as output from "../lib/output.js";
|
|
3
|
+
import { getErrorMessage } from "../lib/errors.js";
|
|
3
4
|
import { NATIVE_SYMBOLS, VALID_CHAINS } from "../lib/chains.js";
|
|
4
|
-
import {
|
|
5
|
+
import { zeroAddress } from "viem";
|
|
6
|
+
import { resolveTokenSymbol } from "../lib/tokens.js";
|
|
5
7
|
/**
|
|
6
8
|
* Resolve a token symbol or address to a contract address for swapping.
|
|
7
9
|
* - The chain's native ticker (ETH/POL/BNB) or the zero address → native, sent
|
|
@@ -12,26 +14,24 @@ async function resolveSwapToken(tokenInput, chain) {
|
|
|
12
14
|
const input = tokenInput.trim();
|
|
13
15
|
const nativeSymbol = NATIVE_SYMBOLS[chain] ?? "ETH";
|
|
14
16
|
const upper = input.toUpperCase();
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
// viem's zeroAddress is already lowercase, so compare against the lowercased input.
|
|
18
|
+
const isNative = upper === nativeSymbol.toUpperCase() || input.toLowerCase() === zeroAddress;
|
|
17
19
|
if (isNative) {
|
|
18
|
-
return { address:
|
|
20
|
+
return { address: zeroAddress, symbol: nativeSymbol };
|
|
19
21
|
}
|
|
20
22
|
return resolveTokenSymbol(input, chain);
|
|
21
23
|
}
|
|
22
24
|
export async function swapCommand(opts) {
|
|
23
25
|
const chain = opts.chain ?? "base";
|
|
24
26
|
if (!VALID_CHAINS.has(chain) || chain === "solana") {
|
|
25
|
-
output.
|
|
26
|
-
process.exit(1);
|
|
27
|
+
output.fatal(`Unsupported chain "${chain}". Swaps support EVM chains: base, polygon, mainnet, unichain, worldchain, arbitrum, bnb.`);
|
|
27
28
|
}
|
|
28
29
|
// Validate amount client-side so a bad value gives a clear error instead of a
|
|
29
30
|
// generic 500 from the API's parseUnits(amount, decimals). Number() alone
|
|
30
31
|
// accepts "1e-3" / "0x10" / "Infinity" that parseUnits rejects, so require a
|
|
31
32
|
// plain decimal string.
|
|
32
33
|
if (!/^\d*\.?\d+$/.test(opts.amount) || Number(opts.amount) <= 0) {
|
|
33
|
-
output.
|
|
34
|
-
process.exit(1);
|
|
34
|
+
output.fatal(`Invalid amount "${opts.amount}". Provide a positive decimal number, e.g. --amount 0.5.`);
|
|
35
35
|
}
|
|
36
36
|
// Resolve from/to tokens (symbol → address, native → zero address)
|
|
37
37
|
let fromToken;
|
|
@@ -45,7 +45,7 @@ export async function swapCommand(opts) {
|
|
|
45
45
|
resolveSpin.stop();
|
|
46
46
|
}
|
|
47
47
|
catch (err) {
|
|
48
|
-
resolveSpin.fail(err
|
|
48
|
+
resolveSpin.fail(getErrorMessage(err));
|
|
49
49
|
process.exit(1);
|
|
50
50
|
}
|
|
51
51
|
// Quote
|
|
@@ -62,7 +62,7 @@ export async function swapCommand(opts) {
|
|
|
62
62
|
quoteSpin.stop();
|
|
63
63
|
}
|
|
64
64
|
catch (err) {
|
|
65
|
-
quoteSpin.fail(`Quote failed: ${err
|
|
65
|
+
quoteSpin.fail(`Quote failed: ${getErrorMessage(err)}`);
|
|
66
66
|
process.exit(1);
|
|
67
67
|
}
|
|
68
68
|
output.blank();
|
|
@@ -100,7 +100,7 @@ export async function swapCommand(opts) {
|
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
catch (err) {
|
|
103
|
-
swapSpin.fail(`Swap failed: ${err
|
|
103
|
+
swapSpin.fail(`Swap failed: ${getErrorMessage(err)}`);
|
|
104
104
|
process.exit(1);
|
|
105
105
|
}
|
|
106
106
|
}
|
package/dist/commands/tokens.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { searchTokens } from "../lib/api.js";
|
|
2
2
|
import * as output from "../lib/output.js";
|
|
3
|
+
import { getErrorMessage } from "../lib/errors.js";
|
|
3
4
|
export async function tokensSearchCommand(query, opts) {
|
|
4
5
|
const spin = output.spinner(`Searching tokens for "${query}"...`);
|
|
5
6
|
try {
|
|
@@ -22,7 +23,7 @@ export async function tokensSearchCommand(query, opts) {
|
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
catch (err) {
|
|
25
|
-
spin.fail(`Search failed: ${err
|
|
26
|
+
spin.fail(`Search failed: ${getErrorMessage(err)}`);
|
|
26
27
|
process.exit(1);
|
|
27
28
|
}
|
|
28
29
|
}
|
|
@@ -37,8 +38,7 @@ export async function tokensInfoCommand(address, opts) {
|
|
|
37
38
|
const token = res.tokens.find((t) => t.address.toLowerCase() === addressLower) ??
|
|
38
39
|
res.tokens[0];
|
|
39
40
|
if (!token) {
|
|
40
|
-
output.
|
|
41
|
-
process.exit(1);
|
|
41
|
+
output.fatal("Token not found. Check the address and try again.");
|
|
42
42
|
}
|
|
43
43
|
console.log();
|
|
44
44
|
output.label("Name", token.name);
|
|
@@ -53,7 +53,7 @@ export async function tokensInfoCommand(address, opts) {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
catch (err) {
|
|
56
|
-
spin.fail(`Failed to fetch token info: ${err
|
|
56
|
+
spin.fail(`Failed to fetch token info: ${getErrorMessage(err)}`);
|
|
57
57
|
process.exit(1);
|
|
58
58
|
}
|
|
59
59
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { transfer, resolveRecipient } from "../lib/api.js";
|
|
2
2
|
import * as output from "../lib/output.js";
|
|
3
|
+
import { getErrorMessage } from "../lib/errors.js";
|
|
3
4
|
import { NATIVE_SYMBOLS } from "../lib/chains.js";
|
|
4
|
-
import { isAddress } from "viem";
|
|
5
|
-
import {
|
|
5
|
+
import { isAddress, zeroAddress } from "viem";
|
|
6
|
+
import { resolveTokenSymbol } from "../lib/tokens.js";
|
|
6
7
|
function looksLikeEnsName(value) {
|
|
7
8
|
const v = value.trim().toLowerCase();
|
|
8
9
|
return v.endsWith(".eth") || v.endsWith(".cb.id");
|
|
@@ -13,8 +14,7 @@ async function resolveTransferRecipient(raw) {
|
|
|
13
14
|
return { address: value, label: value };
|
|
14
15
|
}
|
|
15
16
|
if (!looksLikeEnsName(value)) {
|
|
16
|
-
output.
|
|
17
|
-
process.exit(1);
|
|
17
|
+
output.fatal(`Invalid recipient "${value}". Expected a 0x address or an ENS name (e.g. vitalik.eth, name.base.eth, name.cb.id).`);
|
|
18
18
|
}
|
|
19
19
|
const spin = output.spinner(`Resolving ENS name "${value}"...`);
|
|
20
20
|
try {
|
|
@@ -30,7 +30,7 @@ async function resolveTransferRecipient(raw) {
|
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
32
|
catch (err) {
|
|
33
|
-
spin.fail(`ENS resolution failed for "${value}": ${err
|
|
33
|
+
spin.fail(`ENS resolution failed for "${value}": ${getErrorMessage(err)}`);
|
|
34
34
|
process.exit(1);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -38,8 +38,7 @@ export async function transferCommand(opts) {
|
|
|
38
38
|
const isNative = opts.native ?? false;
|
|
39
39
|
const chain = opts.chain ?? "base";
|
|
40
40
|
if (!isNative && !opts.token) {
|
|
41
|
-
output.
|
|
42
|
-
process.exit(1);
|
|
41
|
+
output.fatal("Token required for ERC20 transfers. Use --token <symbol or address> or --native.");
|
|
43
42
|
}
|
|
44
43
|
const recipient = await resolveTransferRecipient(opts.to);
|
|
45
44
|
const recipientAddress = recipient.address;
|
|
@@ -47,7 +46,8 @@ export async function transferCommand(opts) {
|
|
|
47
46
|
let tokenAddress;
|
|
48
47
|
let tokenLabel;
|
|
49
48
|
if (isNative) {
|
|
50
|
-
|
|
49
|
+
// Zero address = native-token sentinel; the API detects + sanitizes it.
|
|
50
|
+
tokenAddress = zeroAddress;
|
|
51
51
|
tokenLabel = NATIVE_SYMBOLS[chain] ?? "ETH";
|
|
52
52
|
}
|
|
53
53
|
else {
|
|
@@ -64,7 +64,7 @@ export async function transferCommand(opts) {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
catch (err) {
|
|
67
|
-
spin.fail(err
|
|
67
|
+
spin.fail(getErrorMessage(err));
|
|
68
68
|
process.exit(1);
|
|
69
69
|
}
|
|
70
70
|
}
|
|
@@ -86,7 +86,7 @@ export async function transferCommand(opts) {
|
|
|
86
86
|
output.label("Tx Hash", result.txHash ?? "unknown");
|
|
87
87
|
}
|
|
88
88
|
catch (err) {
|
|
89
|
-
spin.fail(`Transfer failed: ${err
|
|
89
|
+
spin.fail(`Transfer failed: ${getErrorMessage(err)}`);
|
|
90
90
|
process.exit(1);
|
|
91
91
|
}
|
|
92
92
|
}
|
package/dist/commands/update.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import { execSync } from "node:child_process";
|
|
3
3
|
import * as output from "../lib/output.js";
|
|
4
|
+
import { getErrorMessage } from "../lib/errors.js";
|
|
4
5
|
const PACKAGE_NAME = "@bankr/cli";
|
|
5
6
|
/**
|
|
6
7
|
* Compare two semver version strings.
|
|
@@ -79,8 +80,7 @@ export async function updateCommand(opts) {
|
|
|
79
80
|
}
|
|
80
81
|
catch (err) {
|
|
81
82
|
spin.fail();
|
|
82
|
-
output.
|
|
83
|
-
process.exit(1);
|
|
83
|
+
output.fatal(getErrorMessage(err));
|
|
84
84
|
}
|
|
85
85
|
const cmp = compareSemver(current, latest);
|
|
86
86
|
if (cmp === 0) {
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
17
17
|
import { join } from "node:path";
|
|
18
18
|
import { confirm } from "@inquirer/prompts";
|
|
19
|
+
import { authHeaders, handleResponse } from "../lib/api.js";
|
|
19
20
|
import * as output from "../lib/output.js";
|
|
20
|
-
import {
|
|
21
|
-
import { getApiUrl, requireApiKey, CLI_USER_AGENT } from "../lib/config.js";
|
|
21
|
+
import { getApiUrl } from "../lib/config.js";
|
|
22
22
|
// ── Config file ─────────────────────────────────────────────────────────
|
|
23
23
|
const CONFIG_FILENAME = "bankr.webhooks.json";
|
|
24
24
|
const WEBHOOKS_DIR = "webhooks";
|
|
@@ -36,8 +36,7 @@ function loadConfigFile(projectRoot) {
|
|
|
36
36
|
return JSON.parse(readFileSync(p, "utf-8"));
|
|
37
37
|
}
|
|
38
38
|
catch {
|
|
39
|
-
output.
|
|
40
|
-
process.exit(1);
|
|
39
|
+
output.fatal(`Failed to parse ${p}. Check that it is valid JSON.`);
|
|
41
40
|
}
|
|
42
41
|
}
|
|
43
42
|
}
|
|
@@ -46,23 +45,6 @@ function loadConfigFile(projectRoot) {
|
|
|
46
45
|
function saveConfigFile(projectRoot, config) {
|
|
47
46
|
writeFileSync(join(projectRoot, CONFIG_FILENAME), JSON.stringify(config, null, 2) + "\n");
|
|
48
47
|
}
|
|
49
|
-
function authHeaders() {
|
|
50
|
-
return {
|
|
51
|
-
"X-API-Key": requireApiKey(),
|
|
52
|
-
"Content-Type": "application/json",
|
|
53
|
-
"User-Agent": CLI_USER_AGENT,
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
async function handleResponse(res) {
|
|
57
|
-
if (!res.ok) {
|
|
58
|
-
const body = (await res
|
|
59
|
-
.json()
|
|
60
|
-
.catch(() => ({ message: res.statusText })));
|
|
61
|
-
const msg = body.message || body.error || res.statusText;
|
|
62
|
-
throw new Error(`API error (${res.status}): ${msg}`);
|
|
63
|
-
}
|
|
64
|
-
return res.json();
|
|
65
|
-
}
|
|
66
48
|
const MAX_WEBHOOK_NAME_LENGTH = 47;
|
|
67
49
|
const WEBHOOK_NAME_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
68
50
|
function validateWebhookName(name) {
|
|
@@ -326,8 +308,7 @@ export default async function handler(req: Request): Promise<Response> {
|
|
|
326
308
|
export async function webhooksAddCommand(name, options = {}) {
|
|
327
309
|
const err = validateWebhookName(name);
|
|
328
310
|
if (err) {
|
|
329
|
-
output.
|
|
330
|
-
process.exit(1);
|
|
311
|
+
output.fatal(err);
|
|
331
312
|
}
|
|
332
313
|
const providerInput = (options.provider ?? "generic").toLowerCase();
|
|
333
314
|
const validProviders = [
|
|
@@ -337,20 +318,17 @@ export async function webhooksAddCommand(name, options = {}) {
|
|
|
337
318
|
"generic",
|
|
338
319
|
];
|
|
339
320
|
if (!validProviders.includes(providerInput)) {
|
|
340
|
-
output.
|
|
341
|
-
process.exit(1);
|
|
321
|
+
output.fatal(`Invalid provider "${providerInput}". Valid: ${validProviders.join(", ")}.`);
|
|
342
322
|
}
|
|
343
323
|
const provider = providerInput;
|
|
344
324
|
const root = findProjectRoot();
|
|
345
325
|
const dir = join(root, WEBHOOKS_DIR);
|
|
346
326
|
if (!existsSync(dir)) {
|
|
347
|
-
output.
|
|
348
|
-
process.exit(1);
|
|
327
|
+
output.fatal(`No ${WEBHOOKS_DIR}/ directory found. Run 'bankr webhooks init' first.`);
|
|
349
328
|
}
|
|
350
329
|
const serviceDir = join(dir, name);
|
|
351
330
|
if (existsSync(serviceDir)) {
|
|
352
|
-
output.
|
|
353
|
-
process.exit(1);
|
|
331
|
+
output.fatal(`Webhook "${name}" already exists at ${WEBHOOKS_DIR}/${name}/`);
|
|
354
332
|
}
|
|
355
333
|
mkdirSync(serviceDir, { recursive: true });
|
|
356
334
|
const { source, envHint } = handlerTemplate(name, provider);
|
|
@@ -397,8 +375,7 @@ export async function webhooksDeployCommand(name) {
|
|
|
397
375
|
const root = findProjectRoot();
|
|
398
376
|
const dir = join(root, WEBHOOKS_DIR);
|
|
399
377
|
if (!existsSync(dir)) {
|
|
400
|
-
output.
|
|
401
|
-
process.exit(1);
|
|
378
|
+
output.fatal(`No ${WEBHOOKS_DIR}/ directory found. Run 'bankr webhooks init' first.`);
|
|
402
379
|
}
|
|
403
380
|
let config = loadConfigFile(root);
|
|
404
381
|
if (!config)
|
|
@@ -413,19 +390,16 @@ export async function webhooksDeployCommand(name) {
|
|
|
413
390
|
}
|
|
414
391
|
}
|
|
415
392
|
if (discovered.length === 0) {
|
|
416
|
-
output.
|
|
417
|
-
process.exit(1);
|
|
393
|
+
output.fatal("No webhooks found. Run 'bankr webhooks add <name>' first.");
|
|
418
394
|
}
|
|
419
395
|
const toDeploy = name ? discovered.filter((s) => s === name) : discovered;
|
|
420
396
|
if (name && toDeploy.length === 0) {
|
|
421
|
-
output.
|
|
422
|
-
process.exit(1);
|
|
397
|
+
output.fatal(`Webhook "${name}" not found in ${WEBHOOKS_DIR}/`);
|
|
423
398
|
}
|
|
424
399
|
for (const svc of toDeploy) {
|
|
425
400
|
const nameError = validateWebhookName(svc);
|
|
426
401
|
if (nameError) {
|
|
427
|
-
output.
|
|
428
|
-
process.exit(1);
|
|
402
|
+
output.fatal(nameError);
|
|
429
403
|
}
|
|
430
404
|
if (!config.webhooks[svc]) {
|
|
431
405
|
config.webhooks[svc] = {
|
|
@@ -487,9 +461,7 @@ export async function webhooksDeployCommand(name) {
|
|
|
487
461
|
output.info("Your handler code is responsible for verifying incoming signatures (Slack, GitHub, etc.). Provider-specific scaffolds include the verifier inline — `bankr webhooks add <name> --provider slack|github|stripe` to scaffold one.");
|
|
488
462
|
}
|
|
489
463
|
catch (err) {
|
|
490
|
-
|
|
491
|
-
output.error(getErrorMessage(err));
|
|
492
|
-
process.exit(1);
|
|
464
|
+
output.failWith(spin, "Deploy failed", err);
|
|
493
465
|
}
|
|
494
466
|
}
|
|
495
467
|
export async function webhooksListCommand() {
|
|
@@ -508,16 +480,16 @@ export async function webhooksListCommand() {
|
|
|
508
480
|
const status = w.status === "active"
|
|
509
481
|
? output.fmt.success("active")
|
|
510
482
|
: output.fmt.warn(w.status);
|
|
511
|
-
const mode = w.readOnly
|
|
483
|
+
const mode = w.readOnly
|
|
484
|
+
? output.fmt.dim("read-only")
|
|
485
|
+
: output.fmt.warn("writes");
|
|
512
486
|
console.log(` ${output.fmt.brand(w.name)} ${status} v${w.version} ${mode} ${w.totalInvocations} invocations`);
|
|
513
487
|
if (w.description)
|
|
514
488
|
output.dim(` ${w.description}`);
|
|
515
489
|
}
|
|
516
490
|
}
|
|
517
491
|
catch (err) {
|
|
518
|
-
|
|
519
|
-
output.error(getErrorMessage(err));
|
|
520
|
-
process.exit(1);
|
|
492
|
+
output.failWith(spin, "Failed to list webhooks", err);
|
|
521
493
|
}
|
|
522
494
|
}
|
|
523
495
|
export async function webhooksPauseResumeCommand(name, action) {
|
|
@@ -533,9 +505,7 @@ export async function webhooksPauseResumeCommand(name, action) {
|
|
|
533
505
|
spin.succeed(`${name} ${action === "pause" ? "paused" : "resumed"}`);
|
|
534
506
|
}
|
|
535
507
|
catch (err) {
|
|
536
|
-
|
|
537
|
-
output.error(getErrorMessage(err));
|
|
538
|
-
process.exit(1);
|
|
508
|
+
output.failWith(spin, `Failed to ${action} ${name}`, err);
|
|
539
509
|
}
|
|
540
510
|
}
|
|
541
511
|
export async function webhooksDeleteCommand(name) {
|
|
@@ -556,15 +526,15 @@ export async function webhooksDeleteCommand(name) {
|
|
|
556
526
|
spin.succeed(`${name} deleted`);
|
|
557
527
|
}
|
|
558
528
|
catch (err) {
|
|
559
|
-
|
|
560
|
-
output.error(getErrorMessage(err));
|
|
561
|
-
process.exit(1);
|
|
529
|
+
output.failWith(spin, `Failed to delete ${name}`, err);
|
|
562
530
|
}
|
|
563
531
|
}
|
|
564
532
|
export async function webhooksLogsCommand(name) {
|
|
565
533
|
const spin = output.spinner(`Fetching invocations for ${name}...`);
|
|
566
534
|
try {
|
|
567
|
-
const res = await fetch(`${getApiUrl()}/webhooks/${name}/logs?limit=25`, {
|
|
535
|
+
const res = await fetch(`${getApiUrl()}/webhooks/${name}/logs?limit=25`, {
|
|
536
|
+
headers: authHeaders(),
|
|
537
|
+
});
|
|
568
538
|
const result = await handleResponse(res);
|
|
569
539
|
spin.stop();
|
|
570
540
|
if (result.logs.length === 0) {
|
|
@@ -582,23 +552,19 @@ export async function webhooksLogsCommand(name) {
|
|
|
582
552
|
}
|
|
583
553
|
}
|
|
584
554
|
catch (err) {
|
|
585
|
-
|
|
586
|
-
output.error(getErrorMessage(err));
|
|
587
|
-
process.exit(1);
|
|
555
|
+
output.failWith(spin, "Failed to fetch logs", err);
|
|
588
556
|
}
|
|
589
557
|
}
|
|
590
558
|
// ── Env vars ────────────────────────────────────────────────────────────
|
|
591
559
|
export async function webhooksEnvSetCommand(keyValue) {
|
|
592
560
|
const eqIdx = keyValue.indexOf("=");
|
|
593
561
|
if (eqIdx === -1) {
|
|
594
|
-
output.
|
|
595
|
-
process.exit(1);
|
|
562
|
+
output.fatal("Usage: bankr webhooks env set KEY=VALUE");
|
|
596
563
|
}
|
|
597
564
|
const key = keyValue.slice(0, eqIdx);
|
|
598
565
|
const value = keyValue.slice(eqIdx + 1);
|
|
599
566
|
if (!key) {
|
|
600
|
-
output.
|
|
601
|
-
process.exit(1);
|
|
567
|
+
output.fatal("Key cannot be empty");
|
|
602
568
|
}
|
|
603
569
|
const spin = output.spinner(`Setting ${key}...`);
|
|
604
570
|
try {
|
|
@@ -611,9 +577,7 @@ export async function webhooksEnvSetCommand(keyValue) {
|
|
|
611
577
|
spin.succeed(`Set ${key}`);
|
|
612
578
|
}
|
|
613
579
|
catch (err) {
|
|
614
|
-
|
|
615
|
-
output.error(getErrorMessage(err));
|
|
616
|
-
process.exit(1);
|
|
580
|
+
output.failWith(spin, `Failed to set ${key}`, err);
|
|
617
581
|
}
|
|
618
582
|
}
|
|
619
583
|
export async function webhooksEnvListCommand() {
|
|
@@ -632,9 +596,7 @@ export async function webhooksEnvListCommand() {
|
|
|
632
596
|
console.log(` ${n}`);
|
|
633
597
|
}
|
|
634
598
|
catch (err) {
|
|
635
|
-
|
|
636
|
-
output.error(getErrorMessage(err));
|
|
637
|
-
process.exit(1);
|
|
599
|
+
output.failWith(spin, "Failed to list env vars", err);
|
|
638
600
|
}
|
|
639
601
|
}
|
|
640
602
|
export async function webhooksEnvUnsetCommand(key) {
|
|
@@ -645,9 +607,7 @@ export async function webhooksEnvUnsetCommand(key) {
|
|
|
645
607
|
spin.succeed(`Removed ${key}`);
|
|
646
608
|
}
|
|
647
609
|
catch (err) {
|
|
648
|
-
|
|
649
|
-
output.error(getErrorMessage(err));
|
|
650
|
-
process.exit(1);
|
|
610
|
+
output.failWith(spin, `Failed to remove ${key}`, err);
|
|
651
611
|
}
|
|
652
612
|
}
|
|
653
613
|
//# sourceMappingURL=webhooks.js.map
|
package/dist/commands/whoami.js
CHANGED
|
@@ -2,13 +2,13 @@ import { existsSync } from "fs";
|
|
|
2
2
|
import { getApiKey, getApiUrl, getConfigPath, isCustomApiUrl, } from "../lib/config.js";
|
|
3
3
|
import { getUserInfo } from "../lib/api.js";
|
|
4
4
|
import * as output from "../lib/output.js";
|
|
5
|
+
import { getErrorMessage } from "../lib/errors.js";
|
|
5
6
|
export async function whoamiCommand() {
|
|
6
7
|
const apiKey = getApiKey();
|
|
7
8
|
const apiUrl = getApiUrl();
|
|
8
9
|
const configPath = getConfigPath();
|
|
9
10
|
if (!apiKey) {
|
|
10
|
-
output.
|
|
11
|
-
process.exit(1);
|
|
11
|
+
output.fatal("Not authenticated. Run `bankr login` to set up your Bankr API key.");
|
|
12
12
|
}
|
|
13
13
|
const source = process.env.BANKR_API_KEY ? "env (BANKR_API_KEY)" : configPath;
|
|
14
14
|
output.label("Bankr API Key", output.maskApiKey(apiKey));
|
|
@@ -35,7 +35,7 @@ export async function whoamiCommand() {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
catch (err) {
|
|
38
|
-
spin.fail(`Could not reach Bankr API: ${err
|
|
38
|
+
spin.fail(`Could not reach Bankr API: ${getErrorMessage(err)}`);
|
|
39
39
|
return;
|
|
40
40
|
}
|
|
41
41
|
// Fetch user profile info
|
|
@@ -69,7 +69,7 @@ export async function whoamiCommand() {
|
|
|
69
69
|
output.label("Score", `${score}${rankStr}`);
|
|
70
70
|
}
|
|
71
71
|
catch (err) {
|
|
72
|
-
profileSpin.fail(`Could not fetch account info: ${err
|
|
72
|
+
profileSpin.fail(`Could not fetch account info: ${getErrorMessage(err)}`);
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
//# sourceMappingURL=whoami.js.map
|
package/dist/commands/x402.d.ts
CHANGED
|
@@ -62,6 +62,9 @@ export declare function x402EnvUnsetCommand(key: string): Promise<void>;
|
|
|
62
62
|
export declare function x402SchemaCommand(url: string, opts?: {
|
|
63
63
|
raw?: boolean;
|
|
64
64
|
}): Promise<void>;
|
|
65
|
+
export declare function checkAdvertisedPrice(advertisedUsd: number | null, callerCapUsd: number): string | null;
|
|
66
|
+
export declare function parseAdvertisedPrice(price: string, currency: string): number | null;
|
|
67
|
+
export declare function outboundMaxPayment(callerCapUsd: number, advertisedUsd: number | null): number;
|
|
65
68
|
export declare function x402CallCommand(url: string, opts?: {
|
|
66
69
|
method?: string;
|
|
67
70
|
body?: string;
|