@kashdao/cli 0.1.0
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/CHANGELOG.md +78 -0
- package/CONTRIBUTING.md +159 -0
- package/LICENSE +21 -0
- package/README.md +868 -0
- package/SECURITY.md +110 -0
- package/dist/account-AVFLEM5D.js +90 -0
- package/dist/account-AVFLEM5D.js.map +1 -0
- package/dist/auth-GUJCVKTD.js +239 -0
- package/dist/auth-GUJCVKTD.js.map +1 -0
- package/dist/chunk-BN2CUM42.js +9 -0
- package/dist/chunk-BN2CUM42.js.map +1 -0
- package/dist/chunk-BRK7KJ4O.js +154 -0
- package/dist/chunk-BRK7KJ4O.js.map +1 -0
- package/dist/chunk-KMBMQIZ7.js +393 -0
- package/dist/chunk-KMBMQIZ7.js.map +1 -0
- package/dist/chunk-LBIRQHX5.js +133 -0
- package/dist/chunk-LBIRQHX5.js.map +1 -0
- package/dist/chunk-MIXOZU2S.js +366 -0
- package/dist/chunk-MIXOZU2S.js.map +1 -0
- package/dist/chunk-QJMF73M5.js +129 -0
- package/dist/chunk-QJMF73M5.js.map +1 -0
- package/dist/chunk-UZNSYATZ.js +680 -0
- package/dist/chunk-UZNSYATZ.js.map +1 -0
- package/dist/chunk-VIADBYFY.js +94 -0
- package/dist/chunk-VIADBYFY.js.map +1 -0
- package/dist/chunk-YHCG2SUC.js +159 -0
- package/dist/chunk-YHCG2SUC.js.map +1 -0
- package/dist/chunk-YJX3JJ4M.js +174 -0
- package/dist/chunk-YJX3JJ4M.js.map +1 -0
- package/dist/client-IOM55ZCS.js +14 -0
- package/dist/client-IOM55ZCS.js.map +1 -0
- package/dist/completion-ZZGX5BQC.js +100 -0
- package/dist/completion-ZZGX5BQC.js.map +1 -0
- package/dist/config-XJL5TSYK.js +690 -0
- package/dist/config-XJL5TSYK.js.map +1 -0
- package/dist/config-store-3ZSYGXMQ.js +44 -0
- package/dist/config-store-3ZSYGXMQ.js.map +1 -0
- package/dist/docs-MDKKSJDC.js +102 -0
- package/dist/docs-MDKKSJDC.js.map +1 -0
- package/dist/eoa-IQ72EIHR.js +551 -0
- package/dist/eoa-IQ72EIHR.js.map +1 -0
- package/dist/errors-WMZIEGQI.js +18 -0
- package/dist/errors-WMZIEGQI.js.map +1 -0
- package/dist/explain-H4EH3KH3.js +165 -0
- package/dist/explain-H4EH3KH3.js.map +1 -0
- package/dist/global-options-XOLJUPTT.js +18 -0
- package/dist/global-options-XOLJUPTT.js.map +1 -0
- package/dist/health-VZEIII74.js +98 -0
- package/dist/health-VZEIII74.js.map +1 -0
- package/dist/help-footer-GTANVDNP.js +43 -0
- package/dist/help-footer-GTANVDNP.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +251 -0
- package/dist/index.js.map +1 -0
- package/dist/intro-PQQTYWR7.js +41 -0
- package/dist/intro-PQQTYWR7.js.map +1 -0
- package/dist/markets-C37JZDPE.js +295 -0
- package/dist/markets-C37JZDPE.js.map +1 -0
- package/dist/output-VCBZ3FM7.js +22 -0
- package/dist/output-VCBZ3FM7.js.map +1 -0
- package/dist/portfolio-2AEPIJIG.js +115 -0
- package/dist/portfolio-2AEPIJIG.js.map +1 -0
- package/dist/protocol-XEQXF2GW.js +1572 -0
- package/dist/protocol-XEQXF2GW.js.map +1 -0
- package/dist/quote-I4DVJ7ZB.js +144 -0
- package/dist/quote-I4DVJ7ZB.js.map +1 -0
- package/dist/schema-PIFQ65TS.js +410 -0
- package/dist/schema-PIFQ65TS.js.map +1 -0
- package/dist/setup-USZ6IODD.js +260 -0
- package/dist/setup-USZ6IODD.js.map +1 -0
- package/dist/stdin-YW2CEQXU.js +28 -0
- package/dist/stdin-YW2CEQXU.js.map +1 -0
- package/dist/trace-IZBYTUFO.js +103 -0
- package/dist/trace-IZBYTUFO.js.map +1 -0
- package/dist/trade-IIZSEXEI.js +586 -0
- package/dist/trade-IIZSEXEI.js.map +1 -0
- package/dist/version-JDK3PEP5.js +117 -0
- package/dist/version-JDK3PEP5.js.map +1 -0
- package/dist/version-check-TDCION37.js +138 -0
- package/dist/version-check-TDCION37.js.map +1 -0
- package/dist/webhooks-PTVRKICZ.js +680 -0
- package/dist/webhooks-PTVRKICZ.js.map +1 -0
- package/dist/with-retry-4FIZG3A7.js +223 -0
- package/dist/with-retry-4FIZG3A7.js.map +1 -0
- package/package.json +99 -0
|
@@ -0,0 +1,680 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/errors.ts
|
|
4
|
+
import {
|
|
5
|
+
KashAbortedError,
|
|
6
|
+
KashAuthenticationError,
|
|
7
|
+
KashAuthorizationError,
|
|
8
|
+
KashConfigurationError as SdkKashConfigurationError,
|
|
9
|
+
KashConflictError,
|
|
10
|
+
KashError,
|
|
11
|
+
KashMaintenanceError,
|
|
12
|
+
KashNetworkError,
|
|
13
|
+
KashNotFoundError,
|
|
14
|
+
KashRateLimitError,
|
|
15
|
+
KashServerError,
|
|
16
|
+
KashTimeoutError,
|
|
17
|
+
KashValidationError
|
|
18
|
+
} from "@kashdao/sdk";
|
|
19
|
+
|
|
20
|
+
// src/error-catalog.ts
|
|
21
|
+
var ERROR_CATALOG = [
|
|
22
|
+
{
|
|
23
|
+
code: "AUTH_REQUIRED",
|
|
24
|
+
summary: "No API key was provided, or the key is invalid / expired / revoked.",
|
|
25
|
+
description: "The Kash public API requires a kash_live_\u2026 or kash_test_\u2026 key on every authenticated route. First-time users should run `kash setup` (interactive wizard). Existing users can `kash auth set-key`, set KASH_API_KEY, or pass --profile to switch to a stored profile.",
|
|
26
|
+
recoverable: true,
|
|
27
|
+
docsUrl: "https://kash.bot/docs/cli/authentication",
|
|
28
|
+
actions: [
|
|
29
|
+
{
|
|
30
|
+
type: "run_command",
|
|
31
|
+
command: "kash setup",
|
|
32
|
+
description: "First-run wizard \u2014 issues a key, configures profile, validates it."
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
type: "run_command",
|
|
36
|
+
command: "kash auth set-key",
|
|
37
|
+
description: "Store an API key for the active profile (paste interactively or pipe via stdin)."
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
type: "set_env",
|
|
41
|
+
variable: "KASH_API_KEY",
|
|
42
|
+
description: "Provide the key via environment variable."
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
type: "open_url",
|
|
46
|
+
url: "mailto:engineering@kash.bot?subject=Kash%20staging%20API%20key%20request",
|
|
47
|
+
description: "Email `engineering@kash.bot` to request a `kash_test_*` staging key (self-service issuance ships with the production launch)."
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
code: "INSUFFICIENT_SCOPE",
|
|
53
|
+
summary: "The API key is valid but lacks the scope this command requires.",
|
|
54
|
+
description: "Authentication succeeded but the key's scope (read-only / trade / admin) doesn't cover the route. Request a key with broader scope, or move to a tier that includes it.",
|
|
55
|
+
recoverable: true,
|
|
56
|
+
docsUrl: "https://docs.kash.bot/developer-docs/rest-api/authentication",
|
|
57
|
+
actions: [
|
|
58
|
+
{
|
|
59
|
+
type: "open_url",
|
|
60
|
+
url: "mailto:engineering@kash.bot?subject=Kash%20API%20key%20scope%20request",
|
|
61
|
+
description: "Email `engineering@kash.bot` for a key with broader scope."
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
code: "RATE_LIMITED",
|
|
67
|
+
summary: "You have exceeded the per-key rate limit for this tier.",
|
|
68
|
+
description: "Slow down or upgrade for higher limits. The error envelope carries `retryAfterMs`; honor it via `kash --max-retries` or back off in your application.",
|
|
69
|
+
recoverable: true,
|
|
70
|
+
docsUrl: "https://kash.bot/docs/api/rate-limits",
|
|
71
|
+
actions: [
|
|
72
|
+
{
|
|
73
|
+
type: "open_url",
|
|
74
|
+
url: "https://kash.bot/pricing",
|
|
75
|
+
description: "Upgrade tier for higher rate limits."
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
code: "NOT_FOUND",
|
|
81
|
+
summary: "The requested resource (market, trade, position) does not exist.",
|
|
82
|
+
description: "Markets and trades are identified by UUID. Confirm the id is correct (especially after copy-paste truncation) and that the resource is visible to the active key.",
|
|
83
|
+
recoverable: true,
|
|
84
|
+
docsUrl: "https://kash.bot/docs/api/errors",
|
|
85
|
+
actions: []
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
code: "CONFLICT",
|
|
89
|
+
summary: "A conflicting request is already in flight or the resource state changed.",
|
|
90
|
+
description: "Common cases: you sent a duplicate Idempotency-Key, the trade is awaiting high-value confirmation, or the market closed between fetch and trade. Inspect the resource before retrying.",
|
|
91
|
+
recoverable: true,
|
|
92
|
+
docsUrl: "https://kash.bot/docs/api/errors",
|
|
93
|
+
actions: [
|
|
94
|
+
{
|
|
95
|
+
type: "run_command",
|
|
96
|
+
command: "kash trade status <id>",
|
|
97
|
+
description: "Inspect the conflicting trade resource. Substitute <id> with the trade UUID.",
|
|
98
|
+
template: true
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
code: "INVALID_INPUT",
|
|
104
|
+
summary: "The request body or arguments failed validation.",
|
|
105
|
+
description: "Check the field names and types against `kash <command> --help` or `kash schema <command>`. USDC amounts are decimal strings with up to 6 fractional digits.",
|
|
106
|
+
recoverable: true,
|
|
107
|
+
docsUrl: "https://kash.bot/docs/cli/commands",
|
|
108
|
+
actions: [
|
|
109
|
+
{
|
|
110
|
+
type: "run_command",
|
|
111
|
+
command: "kash <command> --help",
|
|
112
|
+
description: "Inspect the command signature. Substitute <command> with the failing path (e.g. `trade buy`, `markets list`).",
|
|
113
|
+
template: true
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
type: "run_command",
|
|
117
|
+
command: "kash schema <command>",
|
|
118
|
+
description: "Get the JSON Schema for the command inputs. Substitute <command> with the failing path.",
|
|
119
|
+
template: true
|
|
120
|
+
}
|
|
121
|
+
]
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
code: "MAINTENANCE",
|
|
125
|
+
summary: "The Kash trade pipeline is temporarily disabled (kill switch).",
|
|
126
|
+
description: "API trade processing is halted, typically during incident response or planned maintenance. Read state is unaffected. Honor the `retryAfterMs` and retry once the window closes.",
|
|
127
|
+
recoverable: true,
|
|
128
|
+
docsUrl: "https://docs.kash.bot/developer-docs/api-errors/API_TRADE_PROCESSING_HALTED",
|
|
129
|
+
actions: [
|
|
130
|
+
{
|
|
131
|
+
type: "wait_and_retry",
|
|
132
|
+
delayMs: 3e4,
|
|
133
|
+
description: "Wait 30s then retry. Surface the requestId if the failure persists."
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
code: "TIMEOUT",
|
|
139
|
+
summary: "The request exceeded the SDK timeout (default 30s).",
|
|
140
|
+
description: "Either the server is slow or the network path is degraded. Retry, or pass --timeout-ms to raise the cap. Repeated timeouts are worth investigating against the status page.",
|
|
141
|
+
recoverable: true,
|
|
142
|
+
docsUrl: "https://kash.bot/docs/cli/troubleshooting",
|
|
143
|
+
actions: [
|
|
144
|
+
{
|
|
145
|
+
type: "run_command",
|
|
146
|
+
command: "kash --timeout-ms 60000 <same command>",
|
|
147
|
+
description: "Re-run with a longer timeout. Substitute <same command> with the original invocation tail.",
|
|
148
|
+
template: true
|
|
149
|
+
}
|
|
150
|
+
]
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
code: "NETWORK",
|
|
154
|
+
summary: "A transport-layer failure (DNS, TLS, connection refused) before any HTTP response.",
|
|
155
|
+
description: "The SDK never received a response. Check connectivity to api.kash.bot. The CLI retries network errors automatically; this means retries were exhausted.",
|
|
156
|
+
recoverable: true,
|
|
157
|
+
docsUrl: "https://kash.bot/docs/cli/troubleshooting",
|
|
158
|
+
actions: []
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
code: "ABORTED",
|
|
162
|
+
summary: "The request was cancelled by the caller before it completed.",
|
|
163
|
+
description: "An AbortSignal you passed (or the spinner you cancelled) fired while the request was in flight. The server may or may not have processed the request \u2014 if it did, the side effect already landed. Idempotent requests can be safely retried with the same Idempotency-Key.",
|
|
164
|
+
recoverable: false,
|
|
165
|
+
docsUrl: "https://kash.bot/docs/cli/troubleshooting",
|
|
166
|
+
actions: []
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
code: "SERVER_ERROR",
|
|
170
|
+
summary: "The API returned a 5xx response after retries.",
|
|
171
|
+
description: "The request is safe to retry. If the issue persists, file a bug at https://github.com/KashDAO/cli/issues with the requestId on the error envelope.",
|
|
172
|
+
recoverable: true,
|
|
173
|
+
docsUrl: "https://docs.kash.bot/developer-docs/api-errors/DEPENDENCY_UNAVAILABLE",
|
|
174
|
+
actions: [
|
|
175
|
+
{
|
|
176
|
+
type: "wait_and_retry",
|
|
177
|
+
delayMs: 5e3,
|
|
178
|
+
description: "Wait 5s and retry. The CLI may have already exhausted its retry budget."
|
|
179
|
+
}
|
|
180
|
+
]
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
code: "CONFIGURATION",
|
|
184
|
+
summary: "The CLI configuration file or environment is invalid.",
|
|
185
|
+
description: "The on-disk ~/.kash/config.json failed to parse, an env var (KASH_CHAIN_ID) doesn't match its expected shape, or a per-invocation flag (--max-retries, --timeout-ms, --base-url) was rejected by the SDK. Run `kash config show` to inspect what loaded.",
|
|
186
|
+
recoverable: true,
|
|
187
|
+
docsUrl: "https://kash.bot/docs/cli/configuration",
|
|
188
|
+
actions: [
|
|
189
|
+
{
|
|
190
|
+
type: "run_command",
|
|
191
|
+
command: "kash config show",
|
|
192
|
+
description: "Inspect the loaded configuration and its sources."
|
|
193
|
+
}
|
|
194
|
+
]
|
|
195
|
+
},
|
|
196
|
+
// ─── Direct-mode (kash protocol ...) ─────────────────────────────
|
|
197
|
+
{
|
|
198
|
+
code: "DIRECT_CONFIG_MISSING",
|
|
199
|
+
summary: "Direct-mode configuration is incomplete.",
|
|
200
|
+
description: "Direct-mode commands (`kash protocol ...`) require RPC URL, smart account address, signer key reference, and chain ID. One or more of these is missing from the active profile and the environment. Run `kash config show` to see what's loaded; set the missing fields with `kash config set rpcUrl \u2026`, `kash config set smartAccount 0x\u2026`, etc.",
|
|
201
|
+
recoverable: true,
|
|
202
|
+
docsUrl: "https://kash.bot/docs/cli/direct-mode",
|
|
203
|
+
actions: [
|
|
204
|
+
{
|
|
205
|
+
type: "run_command",
|
|
206
|
+
command: "kash config show",
|
|
207
|
+
description: "Inspect the loaded configuration and source attribution."
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
type: "run_command",
|
|
211
|
+
command: "kash config set rpcUrl https://your-rpc.example.com",
|
|
212
|
+
description: "Set the RPC URL for direct-mode operations."
|
|
213
|
+
}
|
|
214
|
+
]
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
code: "SIGNER_FAILED",
|
|
218
|
+
summary: "The configured signer (file/env/KMS) failed to load or sign.",
|
|
219
|
+
description: "The signer adapter referenced by `signerKeyRef` couldn't load the private key, or signing the UserOp hash failed. Common causes: missing/unreadable file, missing env var, malformed hex, or a KMS permission denial.",
|
|
220
|
+
recoverable: true,
|
|
221
|
+
docsUrl: "https://kash.bot/docs/cli/direct-mode",
|
|
222
|
+
actions: [
|
|
223
|
+
{
|
|
224
|
+
type: "check_input",
|
|
225
|
+
field: "signerKeyRef",
|
|
226
|
+
description: "Verify the signer reference (file:<path> or env:<VAR>) and its target."
|
|
227
|
+
}
|
|
228
|
+
]
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
code: "RPC_FAILED",
|
|
232
|
+
summary: "The RPC endpoint refused the request or timed out.",
|
|
233
|
+
description: "Network call to the configured `rpcUrl` failed. Could be a rate-limit at the RPC provider, a transient network issue, or a misconfigured URL. The protocol-sdk does NOT retry RPC calls \u2014 fail fast so the operator sees the issue.",
|
|
234
|
+
recoverable: true,
|
|
235
|
+
docsUrl: "https://kash.bot/docs/cli/troubleshooting",
|
|
236
|
+
actions: [
|
|
237
|
+
{
|
|
238
|
+
type: "check_input",
|
|
239
|
+
field: "rpcUrl",
|
|
240
|
+
description: "Verify the RPC URL is reachable and the API key (if any) is valid."
|
|
241
|
+
}
|
|
242
|
+
]
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
code: "BUNDLER_REJECTED",
|
|
246
|
+
summary: "The bundler refused to relay the UserOp.",
|
|
247
|
+
description: "Common rejection reasons: replacement-underpriced, sender-mempool-full, gas estimation drift, or a UserOp that the bundler suspects will revert. The error message carries the bundler-specific reason verbatim.",
|
|
248
|
+
recoverable: true,
|
|
249
|
+
docsUrl: "https://kash.bot/docs/cli/direct-mode",
|
|
250
|
+
actions: []
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
code: "TRANSACTION_REVERTED",
|
|
254
|
+
summary: "The UserOp executed but the on-chain call reverted.",
|
|
255
|
+
description: "The transaction landed on-chain but the contract call reverted. The error message carries the decoded revert reason when the protocol-sdk recognises it (e.g. `MarketFrozen`, `InsufficientReserve`). Re-running with `kash protocol simulate` first will catch most reverts before they cost gas.",
|
|
256
|
+
recoverable: false,
|
|
257
|
+
docsUrl: "https://kash.bot/docs/cli/direct-mode",
|
|
258
|
+
actions: [
|
|
259
|
+
{
|
|
260
|
+
type: "run_command",
|
|
261
|
+
command: "kash protocol simulate <market-address> --action <buy|sell> --outcome <i> --amount <n>",
|
|
262
|
+
description: "Dry-run the trade against current chain state before re-submitting. Substitute every <placeholder>.",
|
|
263
|
+
template: true
|
|
264
|
+
}
|
|
265
|
+
]
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
code: "CHAIN_ERROR",
|
|
269
|
+
summary: "A protocol-level chain interaction failed.",
|
|
270
|
+
description: "An on-chain read or simulation returned an unexpected shape, decoded to an unknown revert, or the contract addresses don't match the configured chain ID. Verify the chain ID and that the protocol contracts are deployed at the expected addresses for that chain.",
|
|
271
|
+
recoverable: false,
|
|
272
|
+
docsUrl: "https://kash.bot/docs/cli/direct-mode",
|
|
273
|
+
actions: [
|
|
274
|
+
{
|
|
275
|
+
type: "check_input",
|
|
276
|
+
field: "chainId",
|
|
277
|
+
description: "Confirm chainId matches the network your RPC and bundler target."
|
|
278
|
+
}
|
|
279
|
+
]
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
code: "UNEXPECTED",
|
|
283
|
+
summary: "An unrecognised error escaped the SDK or the CLI.",
|
|
284
|
+
description: "This means the CLI's error mapper didn't recognise the underlying failure \u2014 the most likely cause is an SDK or runtime issue. File an issue with the message, the command, and the runtime info from `kash version --json`.",
|
|
285
|
+
recoverable: false,
|
|
286
|
+
docsUrl: "https://github.com/KashDAO/cli/issues",
|
|
287
|
+
actions: [
|
|
288
|
+
{
|
|
289
|
+
type: "run_command",
|
|
290
|
+
command: "kash version --json",
|
|
291
|
+
description: "Capture runtime info to attach to the bug report."
|
|
292
|
+
}
|
|
293
|
+
]
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
code: "NOOP",
|
|
297
|
+
summary: "No-op exit (Commander emitted output and asked us to stop).",
|
|
298
|
+
description: "Commander's help/version paths don't represent a failure \u2014 it printed `--help` or `--version` output and signalled the CLI to exit cleanly. This code surfaces in JSON-output contexts so consumers know the run completed without doing real work; the human path exits 0 with no error envelope.",
|
|
299
|
+
recoverable: true,
|
|
300
|
+
docsUrl: "https://kash.bot/docs/cli/exit-codes",
|
|
301
|
+
actions: []
|
|
302
|
+
}
|
|
303
|
+
];
|
|
304
|
+
var CATALOG_BY_CODE = new Map(
|
|
305
|
+
ERROR_CATALOG.map((entry) => [entry.code, entry])
|
|
306
|
+
);
|
|
307
|
+
function lookupErrorCode(code) {
|
|
308
|
+
return CATALOG_BY_CODE.get(code);
|
|
309
|
+
}
|
|
310
|
+
function lookupErrorCodeWithFallback(code) {
|
|
311
|
+
const entry = CATALOG_BY_CODE.get(code);
|
|
312
|
+
if (entry) return entry;
|
|
313
|
+
return CATALOG_BY_CODE.get("UNEXPECTED");
|
|
314
|
+
}
|
|
315
|
+
var ERROR_CODES = new Set(ERROR_CATALOG.map((e) => e.code));
|
|
316
|
+
|
|
317
|
+
// src/errors.ts
|
|
318
|
+
var EXIT_CODES = {
|
|
319
|
+
OK: 0,
|
|
320
|
+
GENERIC: 1,
|
|
321
|
+
AUTH: 2
|
|
322
|
+
};
|
|
323
|
+
var CliError = class extends Error {
|
|
324
|
+
code;
|
|
325
|
+
suggestion;
|
|
326
|
+
exitCode;
|
|
327
|
+
requestId;
|
|
328
|
+
/** True iff a sensible retry/recovery path exists. */
|
|
329
|
+
recoverable;
|
|
330
|
+
/** Suggested delay before retrying (rate limit, server error). */
|
|
331
|
+
retryAfterMs;
|
|
332
|
+
/** Stable docs URL agents can fetch for richer context. */
|
|
333
|
+
docsUrl;
|
|
334
|
+
/** Machine-readable next-step hints. Empty array if none. */
|
|
335
|
+
actions;
|
|
336
|
+
cause;
|
|
337
|
+
constructor(message, options) {
|
|
338
|
+
super(message);
|
|
339
|
+
this.name = "CliError";
|
|
340
|
+
const catalogEntry = lookupErrorCodeWithFallback(options.code);
|
|
341
|
+
this.code = options.code;
|
|
342
|
+
this.suggestion = options.suggestion;
|
|
343
|
+
this.exitCode = options.exitCode ?? EXIT_CODES.GENERIC;
|
|
344
|
+
this.requestId = options.requestId;
|
|
345
|
+
this.recoverable = options.recoverable ?? catalogEntry.recoverable;
|
|
346
|
+
this.retryAfterMs = options.retryAfterMs;
|
|
347
|
+
this.docsUrl = options.docsUrl ?? catalogEntry.docsUrl;
|
|
348
|
+
if (options.actionsOverride !== void 0) {
|
|
349
|
+
this.actions = options.actionsOverride;
|
|
350
|
+
} else {
|
|
351
|
+
this.actions = [...options.actions ?? [], ...catalogEntry.actions];
|
|
352
|
+
}
|
|
353
|
+
this.cause = options.cause;
|
|
354
|
+
Error.captureStackTrace?.(this, this.constructor);
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Render the error as the stable JSON envelope agents pin to. Kept
|
|
358
|
+
* as a method so the index.ts emitError can serialise consistently
|
|
359
|
+
* regardless of caller.
|
|
360
|
+
*/
|
|
361
|
+
toEnvelope() {
|
|
362
|
+
return {
|
|
363
|
+
ok: false,
|
|
364
|
+
error: {
|
|
365
|
+
code: this.code,
|
|
366
|
+
message: this.message,
|
|
367
|
+
recoverable: this.recoverable,
|
|
368
|
+
...this.suggestion === void 0 ? {} : { suggestion: this.suggestion },
|
|
369
|
+
...this.retryAfterMs === void 0 ? {} : { retryAfterMs: this.retryAfterMs },
|
|
370
|
+
...this.docsUrl === void 0 ? {} : { docsUrl: this.docsUrl },
|
|
371
|
+
...this.requestId === void 0 ? {} : { requestId: this.requestId },
|
|
372
|
+
actions: this.actions
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
var CliValidationError = class extends CliError {
|
|
378
|
+
constructor(message, suggestion, field) {
|
|
379
|
+
super(message, {
|
|
380
|
+
code: "INVALID_INPUT",
|
|
381
|
+
...suggestion === void 0 ? {} : { suggestion },
|
|
382
|
+
...field === void 0 ? {} : {
|
|
383
|
+
actions: [
|
|
384
|
+
{
|
|
385
|
+
type: "check_input",
|
|
386
|
+
field,
|
|
387
|
+
description: `Verify the value of "${field}".`
|
|
388
|
+
}
|
|
389
|
+
]
|
|
390
|
+
}
|
|
391
|
+
});
|
|
392
|
+
this.name = "CliValidationError";
|
|
393
|
+
}
|
|
394
|
+
};
|
|
395
|
+
var CliConfigurationError = class extends CliError {
|
|
396
|
+
constructor(message, suggestion) {
|
|
397
|
+
super(message, {
|
|
398
|
+
code: "CONFIGURATION",
|
|
399
|
+
...suggestion === void 0 ? {} : { suggestion }
|
|
400
|
+
});
|
|
401
|
+
this.name = "CliConfigurationError";
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
function toCliError(err) {
|
|
405
|
+
if (err instanceof CliError) {
|
|
406
|
+
return err;
|
|
407
|
+
}
|
|
408
|
+
const commander = mapCommanderError(err);
|
|
409
|
+
if (commander) return commander;
|
|
410
|
+
if (err instanceof KashAuthenticationError) {
|
|
411
|
+
return new CliError(err.message, {
|
|
412
|
+
code: "AUTH_REQUIRED",
|
|
413
|
+
exitCode: EXIT_CODES.AUTH,
|
|
414
|
+
suggestion: "First-time setup: run 'kash setup' (interactive wizard). Otherwise: 'kash auth set-key' or set KASH_API_KEY.",
|
|
415
|
+
...err.requestId === void 0 ? {} : { requestId: err.requestId },
|
|
416
|
+
cause: err
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
if (err instanceof KashAuthorizationError) {
|
|
420
|
+
return new CliError(err.message, {
|
|
421
|
+
code: "INSUFFICIENT_SCOPE",
|
|
422
|
+
exitCode: EXIT_CODES.AUTH,
|
|
423
|
+
suggestion: "The API key is valid but is missing the scope this command needs. Email `engineering@kash.bot` to request a key with broader scope.",
|
|
424
|
+
...err.requestId === void 0 ? {} : { requestId: err.requestId },
|
|
425
|
+
cause: err
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
if (err instanceof KashRateLimitError) {
|
|
429
|
+
const retrySec = err.retryAfterSeconds;
|
|
430
|
+
const retryAfterMs = retrySec === void 0 ? void 0 : retrySec * 1e3;
|
|
431
|
+
const suggestion = retrySec !== void 0 ? `Retry in ${String(retrySec)}s. Upgrade for higher limits: https://kash.bot/pricing` : "Slow down request rate. Upgrade for higher limits: https://kash.bot/pricing";
|
|
432
|
+
return new CliError(err.message, {
|
|
433
|
+
code: "RATE_LIMITED",
|
|
434
|
+
suggestion,
|
|
435
|
+
...retryAfterMs === void 0 ? {} : { retryAfterMs },
|
|
436
|
+
...retryAfterMs === void 0 ? {} : {
|
|
437
|
+
actions: [
|
|
438
|
+
{
|
|
439
|
+
type: "wait_and_retry",
|
|
440
|
+
delayMs: retryAfterMs,
|
|
441
|
+
description: `Wait ${String(retrySec)}s then re-run the same command.`
|
|
442
|
+
}
|
|
443
|
+
]
|
|
444
|
+
},
|
|
445
|
+
...err.requestId === void 0 ? {} : { requestId: err.requestId },
|
|
446
|
+
cause: err
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
if (err instanceof KashNotFoundError) {
|
|
450
|
+
return new CliError(err.message, {
|
|
451
|
+
code: "NOT_FOUND",
|
|
452
|
+
suggestion: "Double-check the resource id (markets and trades use UUIDs).",
|
|
453
|
+
...err.requestId === void 0 ? {} : { requestId: err.requestId },
|
|
454
|
+
cause: err
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
if (err instanceof KashConflictError) {
|
|
458
|
+
return new CliError(err.message, {
|
|
459
|
+
code: "CONFLICT",
|
|
460
|
+
suggestion: "A conflicting request is already in flight or the resource state changed underneath you. Inspect the trade with `kash trade status <id>` before retrying.",
|
|
461
|
+
...err.requestId === void 0 ? {} : { requestId: err.requestId },
|
|
462
|
+
cause: err
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
if (err instanceof KashValidationError) {
|
|
466
|
+
return new CliError(err.message, {
|
|
467
|
+
code: "INVALID_INPUT",
|
|
468
|
+
suggestion: "Verify the request shape matches `kash <command> --help`.",
|
|
469
|
+
...err.requestId === void 0 ? {} : { requestId: err.requestId },
|
|
470
|
+
cause: err
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
if (err instanceof KashMaintenanceError) {
|
|
474
|
+
const retrySec = err.retryAfterSeconds;
|
|
475
|
+
const retryAfterMs = retrySec === void 0 ? void 0 : retrySec * 1e3;
|
|
476
|
+
return new CliError(err.message, {
|
|
477
|
+
code: "MAINTENANCE",
|
|
478
|
+
suggestion: "The Kash trade pipeline is temporarily disabled (incident response or planned maintenance). Honor `retryAfterMs` and retry once the window closes.",
|
|
479
|
+
...retryAfterMs === void 0 ? {} : { retryAfterMs },
|
|
480
|
+
...retryAfterMs === void 0 ? {} : {
|
|
481
|
+
actions: [
|
|
482
|
+
{
|
|
483
|
+
type: "wait_and_retry",
|
|
484
|
+
delayMs: retryAfterMs,
|
|
485
|
+
description: `Wait ${String(retrySec)}s before retrying.`
|
|
486
|
+
}
|
|
487
|
+
]
|
|
488
|
+
},
|
|
489
|
+
...err.requestId === void 0 ? {} : { requestId: err.requestId },
|
|
490
|
+
cause: err
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
if (err instanceof KashTimeoutError) {
|
|
494
|
+
return new CliError(err.message, {
|
|
495
|
+
code: "TIMEOUT",
|
|
496
|
+
suggestion: "The request exceeded the configured timeout. Retry, or pass --timeout-ms to raise the cap.",
|
|
497
|
+
...err.requestId === void 0 ? {} : { requestId: err.requestId },
|
|
498
|
+
cause: err
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
if (err instanceof KashNetworkError) {
|
|
502
|
+
const causeStr = `${String(err.message ?? "")} ${String(err.cause?.message ?? "")}`;
|
|
503
|
+
const isDnsError = causeStr.includes("ENOTFOUND") || causeStr.includes("getaddrinfo") || causeStr.includes("EAI_AGAIN") || causeStr.includes("Could not resolve");
|
|
504
|
+
const suggestion = isDnsError ? "The configured API host did not resolve in DNS. For staging, use a `kash_test_*` key \u2014 the CLI auto-routes to `https://api-staging.kash.bot/v1`. For a custom host, pass `--base-url <url>` or set `KASH_BASE_URL`. Production (`https://api.kash.bot/v1`) is not yet live; track launch status at https://docs.kash.bot." : "The request did not reach the API. Check network connectivity and retry.";
|
|
505
|
+
return new CliError(err.message, {
|
|
506
|
+
code: "NETWORK",
|
|
507
|
+
suggestion,
|
|
508
|
+
...err.requestId === void 0 ? {} : { requestId: err.requestId },
|
|
509
|
+
cause: err
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
if (err instanceof KashAbortedError) {
|
|
513
|
+
return new CliError(err.message, {
|
|
514
|
+
code: "ABORTED",
|
|
515
|
+
suggestion: "The request was cancelled before it completed. If the command is idempotent, you can safely retry with the same Idempotency-Key.",
|
|
516
|
+
...err.requestId === void 0 ? {} : { requestId: err.requestId },
|
|
517
|
+
cause: err
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
if (err instanceof KashServerError) {
|
|
521
|
+
return new CliError(err.message, {
|
|
522
|
+
code: "SERVER_ERROR",
|
|
523
|
+
suggestion: "The API returned a 5xx after retries. The request is safe to retry; if the failure persists, file a bug at https://github.com/KashDAO/cli/issues with the requestId.",
|
|
524
|
+
...err.requestId === void 0 ? {} : { requestId: err.requestId },
|
|
525
|
+
cause: err
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
if (err instanceof SdkKashConfigurationError) {
|
|
529
|
+
const firstIssue = err.issues[0];
|
|
530
|
+
const fieldPath = firstIssue?.path.join(".") ?? "";
|
|
531
|
+
return new CliError(err.message, {
|
|
532
|
+
code: "CONFIGURATION",
|
|
533
|
+
suggestion: firstIssue !== void 0 ? `SDK rejected ${fieldPath || "(root)"}: ${firstIssue.message}` : "The SDK rejected the configuration provided to the client.",
|
|
534
|
+
...fieldPath ? {
|
|
535
|
+
actions: [
|
|
536
|
+
{
|
|
537
|
+
type: "check_input",
|
|
538
|
+
field: fieldPath,
|
|
539
|
+
description: `Fix the value of "${fieldPath}" and re-run.`
|
|
540
|
+
}
|
|
541
|
+
]
|
|
542
|
+
} : {},
|
|
543
|
+
cause: err
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
const protocolErrorMapping = mapProtocolError(err);
|
|
547
|
+
if (protocolErrorMapping !== void 0) {
|
|
548
|
+
return protocolErrorMapping;
|
|
549
|
+
}
|
|
550
|
+
if (err instanceof KashError) {
|
|
551
|
+
return new CliError(err.message, {
|
|
552
|
+
code: "UNEXPECTED",
|
|
553
|
+
recoverable: err.isRetryable,
|
|
554
|
+
...err.requestId === void 0 ? {} : { requestId: err.requestId },
|
|
555
|
+
cause: err
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
if (err instanceof Error) {
|
|
559
|
+
return new CliError(err.message, { code: "UNEXPECTED", cause: err });
|
|
560
|
+
}
|
|
561
|
+
return new CliError(String(err), { code: "UNEXPECTED", cause: err });
|
|
562
|
+
}
|
|
563
|
+
function isCommanderError(err) {
|
|
564
|
+
if (!(err instanceof Error)) return false;
|
|
565
|
+
const candidate = err;
|
|
566
|
+
return typeof candidate.code === "string" && candidate.code.startsWith("commander.") && typeof candidate.message === "string";
|
|
567
|
+
}
|
|
568
|
+
function mapCommanderError(err) {
|
|
569
|
+
if (!isCommanderError(err)) return void 0;
|
|
570
|
+
const { code, message } = err;
|
|
571
|
+
if (code === "commander.help" || code === "commander.helpDisplayed" || code === "commander.version") {
|
|
572
|
+
return new CliError("", {
|
|
573
|
+
code: "NOOP",
|
|
574
|
+
exitCode: EXIT_CODES.OK,
|
|
575
|
+
recoverable: false,
|
|
576
|
+
cause: err
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
if (code === "commander.unknownCommand") {
|
|
580
|
+
const match = /Did you mean (\S+?)\??\)?$/m.exec(message);
|
|
581
|
+
const suggested = match?.[1];
|
|
582
|
+
const suggestion = suggested ? `Did you mean \`kash ${suggested}\`? Run \`kash --help\` for the full command tree.` : "Run `kash --help` for the full command tree.";
|
|
583
|
+
return new CliError(stripTrailingNewlines(message), {
|
|
584
|
+
code: "INVALID_INPUT",
|
|
585
|
+
recoverable: true,
|
|
586
|
+
suggestion,
|
|
587
|
+
...suggested === void 0 ? {} : {
|
|
588
|
+
actions: [
|
|
589
|
+
{
|
|
590
|
+
type: "run_command",
|
|
591
|
+
command: `kash ${suggested}`,
|
|
592
|
+
description: "Run the suggested command instead."
|
|
593
|
+
}
|
|
594
|
+
]
|
|
595
|
+
},
|
|
596
|
+
cause: err
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
if (code === "commander.unknownOption") {
|
|
600
|
+
return new CliError(stripTrailingNewlines(message), {
|
|
601
|
+
code: "INVALID_INPUT",
|
|
602
|
+
recoverable: true,
|
|
603
|
+
suggestion: "Run `kash <command> --help` for the supported flags, or `kash docs --json` for the full surface.",
|
|
604
|
+
cause: err
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
if (code === "commander.missingArgument" || code === "commander.missingMandatoryOptionValue" || code === "commander.optionMissingArgument") {
|
|
608
|
+
return new CliError(stripTrailingNewlines(message), {
|
|
609
|
+
code: "INVALID_INPUT",
|
|
610
|
+
recoverable: true,
|
|
611
|
+
suggestion: "Run the command with `--help` to see required arguments.",
|
|
612
|
+
cause: err
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
return new CliError(stripTrailingNewlines(message), {
|
|
616
|
+
code: "INVALID_INPUT",
|
|
617
|
+
recoverable: true,
|
|
618
|
+
cause: err
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
function stripTrailingNewlines(s) {
|
|
622
|
+
return s.replace(/\n+$/, "");
|
|
623
|
+
}
|
|
624
|
+
function mapProtocolError(err) {
|
|
625
|
+
if (!(err instanceof Error)) return void 0;
|
|
626
|
+
switch (err.name) {
|
|
627
|
+
case "KashConfigError": {
|
|
628
|
+
const cliErr = new CliError(err.message, {
|
|
629
|
+
code: "DIRECT_CONFIG_MISSING",
|
|
630
|
+
suggestion: "Set the missing field via `kash config set <field> <value>` (rpcUrl, smartAccount, signerKeyRef, defaultChainId).",
|
|
631
|
+
cause: err
|
|
632
|
+
});
|
|
633
|
+
return cliErr;
|
|
634
|
+
}
|
|
635
|
+
case "KashSignerError":
|
|
636
|
+
return new CliError(err.message, {
|
|
637
|
+
code: "SIGNER_FAILED",
|
|
638
|
+
suggestion: "Verify the signerKeyRef target is readable (file:<path>) or set (env:<NAME>).",
|
|
639
|
+
cause: err
|
|
640
|
+
});
|
|
641
|
+
case "KashChainError":
|
|
642
|
+
return new CliError(err.message, {
|
|
643
|
+
code: "CHAIN_ERROR",
|
|
644
|
+
suggestion: "On-chain read or contract interaction failed unexpectedly.",
|
|
645
|
+
cause: err
|
|
646
|
+
});
|
|
647
|
+
case "KashBundlerError":
|
|
648
|
+
return new CliError(err.message, {
|
|
649
|
+
code: "BUNDLER_REJECTED",
|
|
650
|
+
suggestion: "Inspect the bundler-specific reason in the message and adjust.",
|
|
651
|
+
cause: err
|
|
652
|
+
});
|
|
653
|
+
case "KashSimulationRevertedError":
|
|
654
|
+
return new CliError(err.message, {
|
|
655
|
+
code: "TRANSACTION_REVERTED",
|
|
656
|
+
suggestion: "Re-run with `kash protocol simulate` to see the decoded revert reason.",
|
|
657
|
+
cause: err
|
|
658
|
+
});
|
|
659
|
+
case "KashProtocolError":
|
|
660
|
+
return new CliError(err.message, {
|
|
661
|
+
code: "CHAIN_ERROR",
|
|
662
|
+
suggestion: "Unrecognised protocol-sdk error. File an issue with `kash version --json`.",
|
|
663
|
+
cause: err
|
|
664
|
+
});
|
|
665
|
+
default:
|
|
666
|
+
return void 0;
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
export {
|
|
671
|
+
ERROR_CATALOG,
|
|
672
|
+
lookupErrorCode,
|
|
673
|
+
EXIT_CODES,
|
|
674
|
+
CliError,
|
|
675
|
+
CliValidationError,
|
|
676
|
+
CliConfigurationError,
|
|
677
|
+
toCliError,
|
|
678
|
+
isCommanderError
|
|
679
|
+
};
|
|
680
|
+
//# sourceMappingURL=chunk-UZNSYATZ.js.map
|