@kashdao/cli 0.1.1 → 0.2.1
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 +96 -0
- package/README.md +78 -27
- package/dist/{account-CVJZ3HVT.js → account-QHPOIZ6I.js} +9 -9
- package/dist/{auth-V5WVZBCO.js → auth-TE7BCN5Q.js} +12 -12
- package/dist/{auth-V5WVZBCO.js.map → auth-TE7BCN5Q.js.map} +1 -1
- package/dist/{chunk-MQUJG224.js → chunk-2HFKULGG.js} +2 -2
- package/dist/{chunk-BVFDUI73.js → chunk-2SR77BYA.js} +10 -9
- package/dist/chunk-2SR77BYA.js.map +1 -0
- package/dist/chunk-6QSTFU4R.js +9 -0
- package/dist/{chunk-KAM6KOFD.js.map → chunk-6QSTFU4R.js.map} +1 -1
- package/dist/{chunk-R4NGUZKN.js → chunk-6UU43MF5.js} +5 -3
- package/dist/chunk-6UU43MF5.js.map +1 -0
- package/dist/{chunk-A3IH5HUV.js → chunk-AROIP4EQ.js} +3 -3
- package/dist/chunk-AROIP4EQ.js.map +1 -0
- package/dist/{chunk-QALDZHTX.js → chunk-H2QGFDZP.js} +9 -11
- package/dist/chunk-H2QGFDZP.js.map +1 -0
- package/dist/{chunk-L4AFV2HK.js → chunk-IOLKGV45.js} +3 -3
- package/dist/chunk-IOLKGV45.js.map +1 -0
- package/dist/{chunk-KADB3OKE.js → chunk-VFBQVUL4.js} +2 -2
- package/dist/{chunk-X2VM6VKM.js → chunk-WL7XUYPH.js} +19 -20
- package/dist/chunk-WL7XUYPH.js.map +1 -0
- package/dist/{chunk-N26VGVGB.js → chunk-ZSMI63N3.js} +109 -37
- package/dist/chunk-ZSMI63N3.js.map +1 -0
- package/dist/client-REDY6K7J.js +14 -0
- package/dist/{completion-PK74S3EZ.js → completion-MXTJYK3D.js} +4 -4
- package/dist/{config-T5U6E6KU.js → config-TIJXUJ5N.js} +32 -23
- package/dist/config-TIJXUJ5N.js.map +1 -0
- package/dist/{config-store-UTFDUCKW.js → config-store-INJY4DDT.js} +6 -4
- package/dist/{docs-VA7CJ2ZF.js → docs-M5RZAQ6P.js} +5 -5
- package/dist/{eoa-RL3NLN3H.js → eoa-N55DYIN3.js} +18 -16
- package/dist/eoa-N55DYIN3.js.map +1 -0
- package/dist/{errors-2NNXRNES.js → errors-SMR7X5DU.js} +2 -2
- package/dist/{explain-3SPMWDYX.js → explain-HIDEZVLV.js} +31 -8
- package/dist/explain-HIDEZVLV.js.map +1 -0
- package/dist/{global-options-WFQ6CEFK.js → global-options-YONBFB7N.js} +4 -4
- package/dist/{health-2KD6XUTJ.js → health-LSJKP3NH.js} +9 -9
- package/dist/index.js +31 -28
- package/dist/index.js.map +1 -1
- package/dist/{markets-H6EK2XDE.js → markets-AGL6Q2ES.js} +23 -12
- package/dist/markets-AGL6Q2ES.js.map +1 -0
- package/dist/{output-FGTXXZEQ.js → output-M4NFSWGW.js} +4 -4
- package/dist/{portfolio-R63D5QB2.js → portfolio-RBRVUEYP.js} +11 -11
- package/dist/{portfolio-R63D5QB2.js.map → portfolio-RBRVUEYP.js.map} +1 -1
- package/dist/{protocol-ZB6R25IM.js → protocol-WYQAKN6N.js} +18 -16
- package/dist/protocol-WYQAKN6N.js.map +1 -0
- package/dist/{quote-OF6BTAPQ.js → quote-6CNHU36A.js} +10 -10
- package/dist/redeem-JESSTZ46.js +108 -0
- package/dist/redeem-JESSTZ46.js.map +1 -0
- package/dist/{schema-3HQN4RFL.js → schema-6EXADLRW.js} +12 -8
- package/dist/{schema-3HQN4RFL.js.map → schema-6EXADLRW.js.map} +1 -1
- package/dist/{setup-IIPQXLPL.js → setup-H46GTSVW.js} +8 -8
- package/dist/{trace-WMO3KDHS.js → trace-VDBWWTYL.js} +10 -10
- package/dist/{trade-YBCI6XD2.js → trade-FTSY23QG.js} +10 -10
- package/dist/trade-FTSY23QG.js.map +1 -0
- package/dist/{version-WB2ACHMU.js → version-JTLF3464.js} +7 -7
- package/dist/{version-check-PRAVPFC6.js → version-check-7JGBY6FZ.js} +4 -4
- package/dist/{webhooks-DVS55O4T.js → webhooks-JEWNX5HZ.js} +10 -10
- package/dist/{webhooks-DVS55O4T.js.map → webhooks-JEWNX5HZ.js.map} +1 -1
- package/dist/{with-retry-2MD2CNK2.js → with-retry-DYSHNLG7.js} +12 -6
- package/dist/with-retry-DYSHNLG7.js.map +1 -0
- package/package.json +5 -5
- package/dist/chunk-A3IH5HUV.js.map +0 -1
- package/dist/chunk-BVFDUI73.js.map +0 -1
- package/dist/chunk-KAM6KOFD.js +0 -9
- package/dist/chunk-L4AFV2HK.js.map +0 -1
- package/dist/chunk-N26VGVGB.js.map +0 -1
- package/dist/chunk-QALDZHTX.js.map +0 -1
- package/dist/chunk-R4NGUZKN.js.map +0 -1
- package/dist/chunk-X2VM6VKM.js.map +0 -1
- package/dist/client-75FVHGOH.js +0 -14
- package/dist/config-T5U6E6KU.js.map +0 -1
- package/dist/eoa-RL3NLN3H.js.map +0 -1
- package/dist/explain-3SPMWDYX.js.map +0 -1
- package/dist/markets-H6EK2XDE.js.map +0 -1
- package/dist/protocol-ZB6R25IM.js.map +0 -1
- package/dist/trade-YBCI6XD2.js.map +0 -1
- package/dist/with-retry-2MD2CNK2.js.map +0 -1
- /package/dist/{account-CVJZ3HVT.js.map → account-QHPOIZ6I.js.map} +0 -0
- /package/dist/{chunk-MQUJG224.js.map → chunk-2HFKULGG.js.map} +0 -0
- /package/dist/{chunk-KADB3OKE.js.map → chunk-VFBQVUL4.js.map} +0 -0
- /package/dist/{client-75FVHGOH.js.map → client-REDY6K7J.js.map} +0 -0
- /package/dist/{completion-PK74S3EZ.js.map → completion-MXTJYK3D.js.map} +0 -0
- /package/dist/{config-store-UTFDUCKW.js.map → config-store-INJY4DDT.js.map} +0 -0
- /package/dist/{docs-VA7CJ2ZF.js.map → docs-M5RZAQ6P.js.map} +0 -0
- /package/dist/{errors-2NNXRNES.js.map → errors-SMR7X5DU.js.map} +0 -0
- /package/dist/{global-options-WFQ6CEFK.js.map → global-options-YONBFB7N.js.map} +0 -0
- /package/dist/{health-2KD6XUTJ.js.map → health-LSJKP3NH.js.map} +0 -0
- /package/dist/{output-FGTXXZEQ.js.map → output-M4NFSWGW.js.map} +0 -0
- /package/dist/{quote-OF6BTAPQ.js.map → quote-6CNHU36A.js.map} +0 -0
- /package/dist/{setup-IIPQXLPL.js.map → setup-H46GTSVW.js.map} +0 -0
- /package/dist/{trace-WMO3KDHS.js.map → trace-VDBWWTYL.js.map} +0 -0
- /package/dist/{version-WB2ACHMU.js.map → version-JTLF3464.js.map} +0 -0
- /package/dist/{version-check-PRAVPFC6.js.map → version-check-7JGBY6FZ.js.map} +0 -0
|
@@ -1,17 +1,47 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
HEX_ADDRESS_REGEX
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2SR77BYA.js";
|
|
5
5
|
import {
|
|
6
6
|
CliConfigurationError
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-WL7XUYPH.js";
|
|
8
8
|
|
|
9
9
|
// src/utils/config-store.ts
|
|
10
10
|
import { existsSync } from "fs";
|
|
11
11
|
import { chmod, mkdir, readFile, unlink, writeFile } from "fs/promises";
|
|
12
12
|
import { homedir } from "os";
|
|
13
13
|
import { dirname, join } from "path";
|
|
14
|
+
import {
|
|
15
|
+
inferBaseUrlFromApiKey,
|
|
16
|
+
PRODUCTION_BASE_URL,
|
|
17
|
+
SDK_API_VERSION,
|
|
18
|
+
STAGING_BASE_URL
|
|
19
|
+
} from "@kashdao/sdk";
|
|
14
20
|
import { z } from "zod";
|
|
21
|
+
|
|
22
|
+
// src/utils/chain.ts
|
|
23
|
+
import { formatChainRef, tryParseChainRef } from "@kashdao/sdk";
|
|
24
|
+
var BASE_MAINNET_CHAIN_ID = 8453;
|
|
25
|
+
var LEGACY_NUMERIC_CHAIN_ID = /^[1-9]\d*$/;
|
|
26
|
+
function normaliseChainInput(input) {
|
|
27
|
+
const value = input.trim();
|
|
28
|
+
const ref = tryParseChainRef(LEGACY_NUMERIC_CHAIN_ID.test(value) ? `evm:${value}` : value);
|
|
29
|
+
return ref === void 0 ? void 0 : formatChainRef(ref);
|
|
30
|
+
}
|
|
31
|
+
function protocolEvmChainId(defaultChain) {
|
|
32
|
+
const ref = tryParseChainRef(defaultChain);
|
|
33
|
+
return ref?.type === "evm" ? ref.chainId : BASE_MAINNET_CHAIN_ID;
|
|
34
|
+
}
|
|
35
|
+
function isEvmChain(defaultChain) {
|
|
36
|
+
return tryParseChainRef(defaultChain)?.type === "evm";
|
|
37
|
+
}
|
|
38
|
+
function marketChainLabel(market) {
|
|
39
|
+
if (market.chainRef !== void 0) return market.chainRef;
|
|
40
|
+
if (market.chainId !== void 0) return `evm:${market.chainId}`;
|
|
41
|
+
return "(unknown)";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// src/utils/config-store.ts
|
|
15
45
|
function omitKey(obj, key) {
|
|
16
46
|
const result = {};
|
|
17
47
|
for (const k of Object.keys(obj)) {
|
|
@@ -55,11 +85,21 @@ var customChainSchema = z.object({
|
|
|
55
85
|
entryPointAddress: hexAddressSchema.optional()
|
|
56
86
|
}).strict().optional()
|
|
57
87
|
}).strict();
|
|
88
|
+
var apiVersionSchema = z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "apiVersion must be a YYYY-MM-DD date");
|
|
58
89
|
var cliConfigSchema = z.object({
|
|
59
90
|
// ── Kash-orchestrated mode (API-backed) ─────────────────────────────
|
|
60
91
|
apiKey: z.string().startsWith("kash_", 'API keys start with "kash_"').min(16, "API key looks too short").optional(),
|
|
61
92
|
baseUrl: z.string().url("baseUrl must be a valid URL").optional(),
|
|
62
|
-
|
|
93
|
+
/**
|
|
94
|
+
* The profile's chain, as a chain reference: `solana:mainnet-beta`,
|
|
95
|
+
* `solana:devnet`, `evm:8453`. Stored normalised (see
|
|
96
|
+
* `normaliseChainInput`), so a value on disk always round-trips.
|
|
97
|
+
*/
|
|
98
|
+
defaultChain: z.string().refine((value) => normaliseChainInput(value) === value, {
|
|
99
|
+
message: "defaultChain must be a chain reference such as solana:mainnet-beta or evm:8453"
|
|
100
|
+
}).optional(),
|
|
101
|
+
/** Public-API version this profile pins (`YYYY-MM-DD`), sent as `X-Kash-Api-Version`. */
|
|
102
|
+
apiVersion: apiVersionSchema.optional(),
|
|
63
103
|
// ── Direct mode (`kash protocol …`, on-chain) ───────────────
|
|
64
104
|
/** RPC endpoint for the chain. Consumer-owned; the CLI never proxies. */
|
|
65
105
|
rpcUrl: z.string().url("rpcUrl must be a valid URL").optional(),
|
|
@@ -85,17 +125,12 @@ var cliFileSchema = z.object({
|
|
|
85
125
|
currentProfile: profileNameSchema.optional(),
|
|
86
126
|
profiles: z.record(profileNameSchema, cliConfigSchema).default({})
|
|
87
127
|
}).strict();
|
|
88
|
-
var PRODUCTION_BASE_URL = "https://api.kash.bot/v1";
|
|
89
|
-
var STAGING_BASE_URL = "https://api-staging.kash.bot/v1";
|
|
90
|
-
function inferBaseUrlFromApiKey(apiKey) {
|
|
91
|
-
if (!apiKey) return void 0;
|
|
92
|
-
if (apiKey.startsWith("kash_test_")) return STAGING_BASE_URL;
|
|
93
|
-
if (apiKey.startsWith("kash_live_")) return PRODUCTION_BASE_URL;
|
|
94
|
-
return void 0;
|
|
95
|
-
}
|
|
96
128
|
var DEFAULTS = {
|
|
97
129
|
baseUrl: PRODUCTION_BASE_URL,
|
|
98
|
-
|
|
130
|
+
/** Kash's canonical chain since the 2026-10-01 Solana cutover. */
|
|
131
|
+
defaultChain: "solana:mainnet-beta",
|
|
132
|
+
/** The API version the bundled `@kashdao/sdk` was released against. */
|
|
133
|
+
apiVersion: SDK_API_VERSION
|
|
99
134
|
};
|
|
100
135
|
async function readConfig(opts = {}) {
|
|
101
136
|
const paths = resolveConfigPathsForOverride(opts.configPath);
|
|
@@ -131,8 +166,7 @@ function parseFileContents(raw, file) {
|
|
|
131
166
|
"Run 'kash config reset' to overwrite it with defaults."
|
|
132
167
|
);
|
|
133
168
|
}
|
|
134
|
-
const
|
|
135
|
-
const result = cliFileSchema.safeParse(migrated);
|
|
169
|
+
const result = cliFileSchema.safeParse(migrateFileShape(parsed));
|
|
136
170
|
if (!result.success) {
|
|
137
171
|
const first = result.error.issues[0];
|
|
138
172
|
const path = first?.path.join(".") ?? "(root)";
|
|
@@ -148,15 +182,17 @@ function describeJsonRoot(value) {
|
|
|
148
182
|
if (Array.isArray(value)) return "array";
|
|
149
183
|
return typeof value;
|
|
150
184
|
}
|
|
151
|
-
function
|
|
152
|
-
if (
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
185
|
+
function migrateFileShape(parsed) {
|
|
186
|
+
if (!isPlainObject(parsed)) return parsed;
|
|
187
|
+
if ("version" in parsed || "profiles" in parsed) {
|
|
188
|
+
if (!isPlainObject(parsed["profiles"])) return parsed;
|
|
189
|
+
const profiles = {};
|
|
190
|
+
for (const [name, profile] of Object.entries(parsed["profiles"])) {
|
|
191
|
+
profiles[name] = migrateProfileFields(profile);
|
|
192
|
+
}
|
|
193
|
+
return { ...parsed, profiles };
|
|
158
194
|
}
|
|
159
|
-
const flat = cliConfigSchema.safeParse(
|
|
195
|
+
const flat = cliConfigSchema.safeParse(migrateProfileFields(parsed));
|
|
160
196
|
if (!flat.success) {
|
|
161
197
|
return parsed;
|
|
162
198
|
}
|
|
@@ -166,6 +202,18 @@ function migrateLegacyShape(parsed) {
|
|
|
166
202
|
profiles: { [DEFAULT_PROFILE]: flat.data }
|
|
167
203
|
};
|
|
168
204
|
}
|
|
205
|
+
function migrateProfileFields(profile) {
|
|
206
|
+
if (!isPlainObject(profile) || !("defaultChainId" in profile)) return profile;
|
|
207
|
+
const legacy = profile["defaultChainId"];
|
|
208
|
+
if (typeof legacy !== "number" || !Number.isSafeInteger(legacy)) return profile;
|
|
209
|
+
const defaultChain = normaliseChainInput(String(legacy));
|
|
210
|
+
if (defaultChain === void 0) return profile;
|
|
211
|
+
const rest = omitKey(profile, "defaultChainId");
|
|
212
|
+
return "defaultChain" in rest ? rest : { ...rest, defaultChain };
|
|
213
|
+
}
|
|
214
|
+
function isPlainObject(value) {
|
|
215
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
216
|
+
}
|
|
169
217
|
function emptyFile() {
|
|
170
218
|
return cliFileSchema.parse({ version: 1 });
|
|
171
219
|
}
|
|
@@ -215,22 +263,38 @@ function isTruthyEnv(value) {
|
|
|
215
263
|
function mergeWithEnv(profile, profileName, profileSource) {
|
|
216
264
|
const envApiKey = process.env["KASH_API_KEY"];
|
|
217
265
|
const envBaseUrl = process.env["KASH_BASE_URL"];
|
|
218
|
-
const
|
|
266
|
+
const envChainRaw = process.env["KASH_CHAIN"];
|
|
267
|
+
const envApiVersionRaw = process.env["KASH_API_VERSION"];
|
|
219
268
|
const envRpcUrl = process.env["KASH_RPC_URL"];
|
|
220
269
|
const envSmartAccount = process.env["KASH_SMART_ACCOUNT"];
|
|
221
270
|
const envBundlerUrl = process.env["KASH_BUNDLER_URL"];
|
|
222
271
|
const envBundlerProviderRaw = process.env["KASH_BUNDLER_PROVIDER"];
|
|
223
272
|
const envSignerKeyRef = process.env["KASH_SIGNER_KEY_REF"];
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
273
|
+
if (process.env["KASH_CHAIN_ID"] !== void 0) {
|
|
274
|
+
throw new CliConfigurationError(
|
|
275
|
+
"KASH_CHAIN_ID is no longer read; it was replaced by KASH_CHAIN in @kashdao/cli 0.2.1.",
|
|
276
|
+
`Set KASH_CHAIN to a chain reference instead (e.g. KASH_CHAIN=evm:${process.env["KASH_CHAIN_ID"]} or KASH_CHAIN=solana:mainnet-beta) and unset KASH_CHAIN_ID.`
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
let envChain;
|
|
280
|
+
if (envChainRaw !== void 0) {
|
|
281
|
+
envChain = normaliseChainInput(envChainRaw);
|
|
282
|
+
if (envChain === void 0) {
|
|
283
|
+
throw new CliConfigurationError(
|
|
284
|
+
`KASH_CHAIN is not a chain reference: ${envChainRaw}`,
|
|
285
|
+
"Set KASH_CHAIN to solana:mainnet-beta, solana:devnet, evm:8453 (eip155:8453 is accepted too) or a numeric EVM chain id, or unset it to use the default."
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
let envApiVersion;
|
|
290
|
+
if (envApiVersionRaw !== void 0) {
|
|
291
|
+
if (!apiVersionSchema.safeParse(envApiVersionRaw).success) {
|
|
228
292
|
throw new CliConfigurationError(
|
|
229
|
-
`
|
|
230
|
-
|
|
293
|
+
`KASH_API_VERSION is not a YYYY-MM-DD date: ${envApiVersionRaw}`,
|
|
294
|
+
`Set KASH_API_VERSION to a dated API version such as ${DEFAULTS.apiVersion}, or unset it to use the default.`
|
|
231
295
|
);
|
|
232
296
|
}
|
|
233
|
-
|
|
297
|
+
envApiVersion = envApiVersionRaw;
|
|
234
298
|
}
|
|
235
299
|
let envBundlerProvider;
|
|
236
300
|
if (envBundlerProviderRaw !== void 0) {
|
|
@@ -245,7 +309,8 @@ function mergeWithEnv(profile, profileName, profileSource) {
|
|
|
245
309
|
}
|
|
246
310
|
const apiKey = envApiKey ?? profile.apiKey;
|
|
247
311
|
const baseUrl = envBaseUrl ?? profile.baseUrl ?? inferBaseUrlFromApiKey(apiKey) ?? DEFAULTS.baseUrl;
|
|
248
|
-
const
|
|
312
|
+
const defaultChain = envChain ?? profile.defaultChain ?? DEFAULTS.defaultChain;
|
|
313
|
+
const apiVersion = envApiVersion ?? profile.apiVersion ?? DEFAULTS.apiVersion;
|
|
249
314
|
const rpcUrl = envRpcUrl ?? profile.rpcUrl;
|
|
250
315
|
const smartAccount = envSmartAccount ?? profile.smartAccount;
|
|
251
316
|
const bundlerUrl = envBundlerUrl ?? profile.bundlerUrl;
|
|
@@ -255,7 +320,8 @@ function mergeWithEnv(profile, profileName, profileSource) {
|
|
|
255
320
|
return {
|
|
256
321
|
apiKey,
|
|
257
322
|
baseUrl,
|
|
258
|
-
|
|
323
|
+
defaultChain,
|
|
324
|
+
apiVersion,
|
|
259
325
|
rpcUrl,
|
|
260
326
|
smartAccount,
|
|
261
327
|
bundlerUrl,
|
|
@@ -266,7 +332,8 @@ function mergeWithEnv(profile, profileName, profileSource) {
|
|
|
266
332
|
sources: {
|
|
267
333
|
apiKey: envApiKey ? "env" : profile.apiKey ? "file" : "unset",
|
|
268
334
|
baseUrl: envBaseUrl ? "env" : profile.baseUrl ? "file" : inferBaseUrlFromApiKey(apiKey) ? "inferred" : "default",
|
|
269
|
-
|
|
335
|
+
defaultChain: envChain !== void 0 ? "env" : profile.defaultChain !== void 0 ? "file" : "default",
|
|
336
|
+
apiVersion: envApiVersion !== void 0 ? "env" : profile.apiVersion !== void 0 ? "file" : "default",
|
|
270
337
|
profile: profileSource,
|
|
271
338
|
rpcUrl: envRpcUrl ? "env" : profile.rpcUrl ? "file" : "unset",
|
|
272
339
|
smartAccount: envSmartAccount ? "env" : profile.smartAccount ? "file" : "unset",
|
|
@@ -371,16 +438,21 @@ async function chmodSafe(target, mode) {
|
|
|
371
438
|
}
|
|
372
439
|
|
|
373
440
|
export {
|
|
441
|
+
normaliseChainInput,
|
|
442
|
+
protocolEvmChainId,
|
|
443
|
+
isEvmChain,
|
|
444
|
+
marketChainLabel,
|
|
445
|
+
inferBaseUrlFromApiKey,
|
|
446
|
+
PRODUCTION_BASE_URL,
|
|
447
|
+
STAGING_BASE_URL,
|
|
374
448
|
resolveConfigPaths,
|
|
375
449
|
resolveConfigPathsForOverride,
|
|
376
450
|
DEFAULT_PROFILE,
|
|
377
451
|
cliConfigSchema,
|
|
378
452
|
cliFileSchema,
|
|
379
|
-
PRODUCTION_BASE_URL,
|
|
380
|
-
STAGING_BASE_URL,
|
|
381
|
-
inferBaseUrlFromApiKey,
|
|
382
453
|
DEFAULTS,
|
|
383
454
|
readConfig,
|
|
455
|
+
migrateFileShape,
|
|
384
456
|
updateConfig,
|
|
385
457
|
clearConfigField,
|
|
386
458
|
listProfiles,
|
|
@@ -390,4 +462,4 @@ export {
|
|
|
390
462
|
readWholeFile,
|
|
391
463
|
writeWholeFile
|
|
392
464
|
};
|
|
393
|
-
//# sourceMappingURL=chunk-
|
|
465
|
+
//# sourceMappingURL=chunk-ZSMI63N3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/config-store.ts","../src/utils/chain.ts"],"sourcesContent":["/**\n * Persistent CLI configuration with multi-profile support.\n *\n * The on-disk shape (v1+):\n *\n * {\n * \"version\": 1,\n * \"currentProfile\": \"default\",\n * \"profiles\": {\n * \"default\": { \"apiKey\": \"kash_live_…\", \"defaultChain\": \"solana:mainnet-beta\" },\n * \"test\": { \"apiKey\": \"kash_test_…\" }\n * }\n * }\n *\n * Flat-shape configs from earlier CLI versions are migrated transparently\n * on first read into a `default` profile, and a 0.1.x numeric\n * `defaultChainId` becomes a `defaultChain` chain reference (`8453` →\n * `evm:8453`). The on-disk file is rewritten in the new shape only on\n * the next write — readers don't mutate state.\n *\n * The file is created and re-written at mode `0600` on POSIX. The\n * directory is created with `0700`. chmod is best-effort — Windows and\n * some network filesystems silently ignore it.\n *\n * Resolution order (highest precedence first):\n *\n * 1. Environment variables: `KASH_API_KEY`, `KASH_BASE_URL`,\n * `KASH_CHAIN`, `KASH_API_VERSION`. Always win.\n * 2. The active profile's fields.\n * 3. Built-in defaults (api.kash.bot/v1, chain `solana:mainnet-beta`,\n * the API version `@kashdao/sdk` pins).\n *\n * Active-profile resolution (highest precedence first):\n *\n * 1. Explicit `--profile <name>` flag (via `options.profile`).\n * 2. `KASH_PROFILE` env var.\n * 3. `currentProfile` field in the config file.\n * 4. `'default'`.\n *\n * Pinning env-var precedence makes CI runs predictable and lets a\n * human override a profile field without editing the file.\n */\n\nimport { existsSync } from 'node:fs';\nimport { chmod, mkdir, readFile, unlink, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\n\nimport {\n inferBaseUrlFromApiKey,\n PRODUCTION_BASE_URL,\n SDK_API_VERSION,\n STAGING_BASE_URL,\n} from '@kashdao/sdk';\nimport { z } from 'zod';\n\nimport { CliConfigurationError } from '../errors.js';\n\nimport { normaliseChainInput } from './chain.js';\nimport { HEX_ADDRESS_REGEX } from './trade-input.js';\n\n/**\n * Return a shallow copy of `obj` without the named property. Cleaner\n * than the `const { [k]: _removed, ...rest } = obj` rest-spread idiom\n * because it avoids the unused-variable lint dance.\n */\nfunction omitKey<T extends Record<string, unknown>, K extends keyof T>(obj: T, key: K): Omit<T, K> {\n const result: Record<string, unknown> = {};\n for (const k of Object.keys(obj)) {\n if (k !== key) result[k] = obj[k];\n }\n return result as Omit<T, K>;\n}\n\n/** Filesystem layout for the config — exposed for tests to override `home`. */\nexport type ConfigPaths = {\n readonly home: string;\n readonly dir: string;\n readonly file: string;\n};\n\nexport function resolveConfigPaths(home: string = homedir()): ConfigPaths {\n const dir = join(home, '.kash');\n return { home, dir, file: join(dir, 'config.json') };\n}\n\n/**\n * Resolve config paths with an optional explicit override path\n * (typically from the `--config` flag or `KASH_CONFIG` env var). The\n * explicit override sets the file directly and derives `dir`/`home`\n * from it for chmod-on-write.\n */\nexport function resolveConfigPathsForOverride(\n override: string | undefined,\n envOverride: string | undefined = process.env['KASH_CONFIG']\n): ConfigPaths {\n const explicit = override ?? envOverride;\n if (explicit) {\n const dir = dirname(explicit);\n return { home: dirname(dir), dir, file: explicit };\n }\n return resolveConfigPaths();\n}\n\nexport const DEFAULT_PROFILE = 'default';\n\n/**\n * Profile-name reserved words. Even though the regex below already\n * blocks the most-dangerous shapes (no `[`, no `<`, no whitespace),\n * the `__proto__` / `constructor` / `prototype` strings ARE allowed\n * by `[A-Za-z0-9_.-]+` — and using them as keys on a plain object\n * (`file.profiles`) walks the prototype chain on read. The denylist\n * makes the prototype-walk impossible at the schema layer.\n *\n * Defence-in-depth: the file format already uses `Object.create(null)`\n * boundaries downstream where possible, but pinning the validator\n * here makes the invariant grep-discoverable.\n */\nconst RESERVED_PROFILE_NAMES = new Set(['__proto__', 'constructor', 'prototype']);\n\n/** Profile name validator — keeps file structure deterministic. */\nconst profileNameSchema = z\n .string()\n .min(1, 'profile name cannot be empty')\n .max(64, 'profile name must be ≤ 64 characters')\n .regex(/^[A-Za-z0-9_.-]+$/, 'profile name allows letters, digits, underscore, dot, and dash only')\n .refine((name) => !RESERVED_PROFILE_NAMES.has(name), {\n message:\n 'profile name uses a reserved word (__proto__, constructor, prototype) — would walk the object prototype chain',\n });\n\n/**\n * Schema for a single profile. Every field is optional so the profile\n * can hold partial state — e.g. only override `baseUrl` while\n * inheriting the API key from env.\n */\n/**\n * Reference to a private key the CLI will load when constructing the\n * direct-mode signer. We never persist the raw key — only a reference\n * to where to read it from at invocation time:\n *\n * - `file:<path>` — read the key from a file (mode 0600 enforced\n * at read time, not write).\n * - `env:<name>` — read the key from an environment variable.\n *\n * This keeps `~/.kash/config.json` free of secret material; the\n * config file itself is only `0600`-protected for the API key, not\n * for arbitrary private keys that could fund-drain a smart account.\n *\n * Future extensions: `keystore:<path>`, `aws-kms:<key-id>`,\n * `gcp-kms:<resource>`, `ledger:<derivation-path>`.\n */\nconst signerKeyRefSchema = z\n .string()\n .regex(/^(file:|env:)\\S+$/, 'signerKeyRef must start with \"file:<path>\" or \"env:<NAME>\"');\n\n/** Bundler provider preset. */\nconst bundlerProviderSchema = z.enum(['flashbots', 'pimlico', 'alchemy', 'generic']);\n\nconst hexAddressSchema = z\n .string()\n .regex(HEX_ADDRESS_REGEX, 'must be a 0x-prefixed 40-char hex address');\n\n/**\n * Custom-chain config — bypasses the protocol-sdk's static chain\n * registry. Required for any chain Kash hasn't deployed canonical\n * contracts on (local Anvil, Hardhat, Tenderly forks, sidechains).\n *\n * The CLI derives the `viemChain` argument the SDK needs from the\n * profile's `defaultChain` (an `evm:` chain) + `rpcUrl` + `customChain.name`; the\n * consumer never has to hand-construct a viem Chain. `addresses`\n * mirrors the SDK's `CustomChainAddresses`. `smartAccount` is required\n * only when the consumer is using SA mode (`kash protocol …`) on a\n * custom chain — EOA mode ignores it.\n */\n/**\n * Custom-chain schema. Every field is optional at the persistence\n * layer because `kash config set customChain.<leaf>` writes one leaf\n * at a time — requiring the full shape at write time would force the\n * user into a single mega-set call. Completeness (name +\n * factoryAddress + usdcAddress required, smartAccount triple all-or-\n * nothing) is enforced at use time in `resolveCliCustomChain`,\n * where the missing field has actionable error context (the SDK call\n * that needs it).\n */\nconst customChainSchema = z\n .object({\n /** Human-readable label, surfaced on `client.addresses.name`. */\n name: z.string().min(1, 'customChain.name must not be empty').optional(),\n factoryAddress: hexAddressSchema.optional(),\n usdcAddress: hexAddressSchema.optional(),\n oracleAddress: hexAddressSchema.optional(),\n vaultAddress: hexAddressSchema.optional(),\n tokens1155Address: hexAddressSchema.optional(),\n paramRegistryAddress: hexAddressSchema.optional(),\n /** Smart-account factory + EntryPoint config (SA mode only). */\n smartAccount: z\n .object({\n factoryAddress: hexAddressSchema.optional(),\n implementationAddress: hexAddressSchema.optional(),\n entryPointAddress: hexAddressSchema.optional(),\n })\n .strict()\n .optional(),\n })\n .strict();\n\nconst apiVersionSchema = z\n .string()\n .regex(/^\\d{4}-\\d{2}-\\d{2}$/, 'apiVersion must be a YYYY-MM-DD date');\n\nexport const cliConfigSchema = z\n .object({\n // ── Kash-orchestrated mode (API-backed) ─────────────────────────────\n apiKey: z\n .string()\n .startsWith('kash_', 'API keys start with \"kash_\"')\n .min(16, 'API key looks too short')\n .optional(),\n baseUrl: z.string().url('baseUrl must be a valid URL').optional(),\n /**\n * The profile's chain, as a chain reference: `solana:mainnet-beta`,\n * `solana:devnet`, `evm:8453`. Stored normalised (see\n * `normaliseChainInput`), so a value on disk always round-trips.\n */\n defaultChain: z\n .string()\n .refine((value) => normaliseChainInput(value) === value, {\n message: 'defaultChain must be a chain reference such as solana:mainnet-beta or evm:8453',\n })\n .optional(),\n /** Public-API version this profile pins (`YYYY-MM-DD`), sent as `X-Kash-Api-Version`. */\n apiVersion: apiVersionSchema.optional(),\n\n // ── Direct mode (`kash protocol …`, on-chain) ───────────────\n /** RPC endpoint for the chain. Consumer-owned; the CLI never proxies. */\n rpcUrl: z.string().url('rpcUrl must be a valid URL').optional(),\n /** Smart account address (the ERC-4337 account whose funds are used). */\n smartAccount: z\n .string()\n .regex(HEX_ADDRESS_REGEX, 'smartAccount must be a 0x-prefixed 40-char hex address')\n .optional(),\n /** Bundler URL (overrides the protocol-sdk's Flashbots Protect default). */\n bundlerUrl: z.string().url('bundlerUrl must be a valid URL').optional(),\n /** Bundler provider preset (selects the right header dialect). */\n bundlerProvider: bundlerProviderSchema.optional(),\n /** Reference to the EOA private key that owns the smart account. */\n signerKeyRef: signerKeyRefSchema.optional(),\n /**\n * Custom-chain addresses for chains outside the static registry\n * (local Anvil, forks, sidechains). When present, the CLI's\n * direct-mode and EOA-mode commands use these addresses instead\n * of looking the chain up in the registry. Required for chainId\n * 31337 (Anvil); optional for Base mainnet/testnet (registry covers them).\n */\n customChain: customChainSchema.optional(),\n })\n .strict();\n\nexport type CliConfig = z.infer<typeof cliConfigSchema>;\n\n/**\n * Schema for the v1 multi-profile file shape.\n *\n * `currentProfile` is intentionally optional (no `.default()`) so the\n * source-attribution logic in `pickProfileName` can distinguish\n * \"user explicitly persisted `default` via `kash config use default`\"\n * (source: 'file') from \"we fell through to the built-in default\n * because the file didn't carry a `currentProfile` field\" (source:\n * 'default'). Both result in `'default'` as the active profile, but\n * the source attribution they report is different.\n */\nconst cliFileSchema = z\n .object({\n version: z.literal(1),\n currentProfile: profileNameSchema.optional(),\n profiles: z.record(profileNameSchema, cliConfigSchema).default({}),\n })\n .strict();\n\nexport type CliFile = z.infer<typeof cliFileSchema>;\n\n/**\n * Canonical API base URLs and key-prefix routing, taken from\n * `@kashdao/sdk` rather than mirrored.\n *\n * The CLI auto-routes on the API-key prefix: a `kash_test_*` key targets\n * staging, a `kash_live_*` key (or no key) targets production. An explicit\n * `baseUrl` config or `KASH_BASE_URL` env var always wins, so a consumer can\n * still point at a private mirror, a local mock, or a future region.\n *\n * These were previously re-declared here with values byte-identical to the\n * SDK's, under a comment promising the two agreed. Both packages are\n * PUBLISHED, and unlike a definitional constant these are deployment facts\n * that change: a host move or a new key prefix updates the SDK, which owns the\n * wire contract, and a copy here would keep routing a live key somewhere else\n * while claiming to match. `no-redeclared-dependency-constant` holds the rule.\n */\nexport { inferBaseUrlFromApiKey, PRODUCTION_BASE_URL, STAGING_BASE_URL };\n\n/** Default values applied when a field is missing from both file and env. */\nexport const DEFAULTS = {\n baseUrl: PRODUCTION_BASE_URL,\n /** Kash's canonical chain since the 2026-10-01 Solana cutover. */\n defaultChain: 'solana:mainnet-beta',\n /** The API version the bundled `@kashdao/sdk` was released against. */\n apiVersion: SDK_API_VERSION,\n} as const;\n\nexport type ResolvedConfig = {\n // ── Kash-orchestrated fields ──────────────────────────────────────────\n readonly apiKey: string | undefined;\n readonly baseUrl: string;\n /** Normalised chain reference (`solana:mainnet-beta`, `evm:8453`). */\n readonly defaultChain: string;\n /** Public-API version sent on every request (`YYYY-MM-DD`). */\n readonly apiVersion: string;\n // ── Direct-mode fields (`kash protocol …`) ────────────────────\n readonly rpcUrl: string | undefined;\n readonly smartAccount: string | undefined;\n readonly bundlerUrl: string | undefined;\n readonly bundlerProvider: 'flashbots' | 'pimlico' | 'alchemy' | 'generic' | undefined;\n readonly signerKeyRef: string | undefined;\n /**\n * Custom-chain config — present only when the profile explicitly sets\n * `customChain.*`. Bypasses the protocol-sdk's static chain registry\n * and is required for chains the registry doesn't cover (Anvil,\n * forks, sidechains).\n */\n readonly customChain: CliConfig['customChain'];\n // ── Meta ──────────────────────────────────────────────────────\n /** Active profile name. */\n readonly profile: string;\n /** Where each non-default value came from — useful for `kash config show`. */\n readonly sources: {\n readonly apiKey: 'env' | 'file' | 'unset';\n readonly baseUrl: 'env' | 'file' | 'inferred' | 'default';\n readonly defaultChain: 'env' | 'file' | 'default';\n readonly apiVersion: 'env' | 'file' | 'default';\n readonly profile: 'flag' | 'env' | 'file' | 'default';\n readonly rpcUrl: 'env' | 'file' | 'unset';\n readonly smartAccount: 'env' | 'file' | 'unset';\n readonly bundlerUrl: 'env' | 'file' | 'unset';\n readonly bundlerProvider: 'env' | 'file' | 'unset';\n readonly signerKeyRef: 'env' | 'file' | 'unset';\n readonly customChain: 'file' | 'unset';\n };\n};\n\nexport type ReadConfigOptions = {\n /** Override which profile to read; takes precedence over env + file. */\n readonly profile?: string;\n /** Override the config file path; takes precedence over `KASH_CONFIG`. */\n readonly configPath?: string;\n};\n\n/**\n * Read the config file and return the resolved active profile merged\n * with environment variables and defaults.\n */\nexport async function readConfig(opts: ReadConfigOptions = {}): Promise<ResolvedConfig> {\n const paths = resolveConfigPathsForOverride(opts.configPath);\n const file = await readFileConfig(paths);\n return resolveActive(file, opts.profile);\n}\n\nasync function readFileConfig(paths: ConfigPaths): Promise<CliFile> {\n if (!existsSync(paths.file)) return emptyFile();\n let raw: string;\n try {\n raw = await readFile(paths.file, 'utf8');\n } catch (cause) {\n throw new CliConfigurationError(\n `Failed to read config file at ${paths.file}: ${(cause as Error).message}`,\n \"Run 'kash config reset' to start fresh.\"\n );\n }\n return parseFileContents(raw, paths.file);\n}\n\nfunction parseFileContents(raw: string, file: string): CliFile {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (cause) {\n throw new CliConfigurationError(\n `Config file at ${file} is not valid JSON: ${(cause as Error).message}`,\n \"Run 'kash config reset' to overwrite it with defaults.\"\n );\n }\n // Guard against valid-JSON-but-wrong-top-level (e.g. someone wrote\n // a string, a number, an array, or `null` to the file). Without this,\n // the v1 schema's \"Expected object, received string\" Zod error\n // bubbles up with no actionable hint.\n if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new CliConfigurationError(\n `Config file at ${file} must contain a JSON object at the top level (got ${describeJsonRoot(parsed)}).`,\n \"Run 'kash config reset' to overwrite it with defaults.\"\n );\n }\n const result = cliFileSchema.safeParse(migrateFileShape(parsed));\n if (!result.success) {\n const first = result.error.issues[0];\n const path = first?.path.join('.') ?? '(root)';\n throw new CliConfigurationError(\n `Config file at ${file} is invalid (${path}): ${first?.message ?? 'validation failed'}`,\n \"Run 'kash config reset' to overwrite it with defaults.\"\n );\n }\n return result.data;\n}\n\n/** Describe a non-object JSON root for the user-facing error message. */\nfunction describeJsonRoot(value: unknown): string {\n if (value === null) return 'null';\n if (Array.isArray(value)) return 'array';\n return typeof value;\n}\n\n/**\n * Bring a config written by an earlier CLI version up to the current\n * shape. Two migrations, both pure:\n *\n * - The legacy flat shape ({ apiKey?, baseUrl?, defaultChainId? } at the\n * root) is wrapped as the `default` profile of a v1 file.\n * - A 0.1.x profile's numeric `defaultChainId` becomes `defaultChain`,\n * the chain reference that can also name Solana: `8453` → `evm:8453`.\n *\n * Anything that does not look like an old shape passes through untouched so\n * the v1 schema raises its structured error. Used by every reader of the file\n * and by `kash config import`, so an exported 0.1.x config imports cleanly.\n */\nexport function migrateFileShape(parsed: unknown): unknown {\n if (!isPlainObject(parsed)) return parsed;\n if ('version' in parsed || 'profiles' in parsed) {\n if (!isPlainObject(parsed['profiles'])) return parsed;\n const profiles: Record<string, unknown> = {};\n for (const [name, profile] of Object.entries(parsed['profiles'])) {\n profiles[name] = migrateProfileFields(profile);\n }\n return { ...parsed, profiles };\n }\n // Legacy flat shape — wrap it as the default profile.\n const flat = cliConfigSchema.safeParse(migrateProfileFields(parsed));\n if (!flat.success) {\n return parsed; // let the v1 schema raise the structured error\n }\n return {\n version: 1,\n currentProfile: DEFAULT_PROFILE,\n profiles: { [DEFAULT_PROFILE]: flat.data },\n };\n}\n\n/**\n * Rename a 0.1.x `defaultChainId` to `defaultChain`. A non-integer value is\n * left in place so the strict schema rejects it by name rather than this\n * function guessing; an explicit `defaultChain` beside it wins.\n */\nfunction migrateProfileFields(profile: unknown): unknown {\n if (!isPlainObject(profile) || !('defaultChainId' in profile)) return profile;\n const legacy = profile['defaultChainId'];\n if (typeof legacy !== 'number' || !Number.isSafeInteger(legacy)) return profile;\n const defaultChain = normaliseChainInput(String(legacy));\n if (defaultChain === undefined) return profile;\n const rest = omitKey(profile, 'defaultChainId');\n return 'defaultChain' in rest ? rest : { ...rest, defaultChain };\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction emptyFile(): CliFile {\n return cliFileSchema.parse({ version: 1 });\n}\n\n/**\n * Compute the active profile name. Order: explicit flag > env >\n * file's `currentProfile` (when present) > built-in `'default'`.\n *\n * Crucially, when the file persists `currentProfile: \"default\"`\n * (e.g. after `kash config use default`), source is `'file'` — not\n * `'default'`. That keeps the JSON contract honest: agents debugging\n * \"why is my profile X?\" need to know it came from a write, not a\n * fallback.\n */\nfunction pickProfileName(\n file: CliFile,\n flagOverride: string | undefined\n): { name: string; source: 'flag' | 'env' | 'file' | 'default' } {\n if (flagOverride !== undefined) {\n validateProfileName(flagOverride, '--profile flag');\n return { name: flagOverride, source: 'flag' };\n }\n const env = process.env['KASH_PROFILE'];\n if (env !== undefined && env.length > 0) {\n validateProfileName(env, 'KASH_PROFILE environment variable');\n return { name: env, source: 'env' };\n }\n if (file.currentProfile !== undefined) {\n return { name: file.currentProfile, source: 'file' };\n }\n return { name: DEFAULT_PROFILE, source: 'default' };\n}\n\n/**\n * Wrap `profileNameSchema.parse` so a malformed value surfaces as a\n * typed `CliConfigurationError` with a `check_input`-friendly\n * suggestion, instead of a raw `ZodError` that the top-level\n * boundary maps to `UNEXPECTED`.\n */\nfunction validateProfileName(value: string, source: string): void {\n const result = profileNameSchema.safeParse(value);\n if (!result.success) {\n const issue = result.error.issues[0];\n throw new CliConfigurationError(\n `Profile name from ${source} is invalid: ${issue?.message ?? 'validation failed'}.`,\n 'Profile names accept letters, digits, underscore, dot, and dash; must be 1-64 characters.'\n );\n }\n}\n\nfunction resolveActive(file: CliFile, flagOverride: string | undefined): ResolvedConfig {\n const { name: profileName, source: profileSource } = pickProfileName(file, flagOverride);\n const profile = file.profiles[profileName];\n // It's not an error to ask for a profile that isn't in the file —\n // env-only setups (CI, agents) are normal. We surface this via the\n // `sources.apiKey === 'unset'` value if no env var fills the gap.\n //\n // BUT: when the missing profile was named via `KASH_PROFILE` or\n // `--profile`, an intentional env-only setup is the rare case and\n // a typo (e.g. `KASH_PROFILE=staing` vs `staging`) is the common\n // case. The operator otherwise sees an empty config + a confusing\n // `AUTH_REQUIRED` later. Nudge them on stderr (no JSON pollution,\n // no behaviour change). `KASH_QUIET=1` mutes the warning for CI.\n if (\n profile === undefined &&\n (profileSource === 'env' || profileSource === 'flag') &&\n Object.keys(file.profiles).length > 0 &&\n !isTruthyEnv(process.env['KASH_QUIET'])\n ) {\n const known = Object.keys(file.profiles).sort().join(', ');\n const sourceLabel = profileSource === 'env' ? 'KASH_PROFILE' : '--profile';\n process.stderr.write(\n `\\u26a0 Profile \"${profileName}\" (${sourceLabel}) is not in the config file. ` +\n `Known profiles: ${known}. ` +\n `Did you typo the name? (Set KASH_QUIET=1 to mute this warning.)\\n`\n );\n }\n return mergeWithEnv(profile ?? {}, profileName, profileSource);\n}\n\n/** Same truthy-env recognizer as `utils/global-options.ts:isTruthyEnv`. */\nfunction isTruthyEnv(value: string | undefined): boolean {\n if (value === undefined) return false;\n const v = value.trim().toLowerCase();\n return v === '1' || v === 'true' || v === 'yes' || v === 'on';\n}\n\nfunction mergeWithEnv(\n profile: CliConfig,\n profileName: string,\n profileSource: 'flag' | 'env' | 'file' | 'default'\n): ResolvedConfig {\n const envApiKey = process.env['KASH_API_KEY'];\n const envBaseUrl = process.env['KASH_BASE_URL'];\n const envChainRaw = process.env['KASH_CHAIN'];\n const envApiVersionRaw = process.env['KASH_API_VERSION'];\n // Direct-mode env vars\n const envRpcUrl = process.env['KASH_RPC_URL'];\n const envSmartAccount = process.env['KASH_SMART_ACCOUNT'];\n const envBundlerUrl = process.env['KASH_BUNDLER_URL'];\n const envBundlerProviderRaw = process.env['KASH_BUNDLER_PROVIDER'];\n const envSignerKeyRef = process.env['KASH_SIGNER_KEY_REF'];\n\n // 0.1.x read a numeric KASH_CHAIN_ID. Ignoring it would silently move a\n // CI job that set it onto the new Solana default, so refuse instead.\n if (process.env['KASH_CHAIN_ID'] !== undefined) {\n throw new CliConfigurationError(\n 'KASH_CHAIN_ID is no longer read; it was replaced by KASH_CHAIN in @kashdao/cli 0.2.1.',\n `Set KASH_CHAIN to a chain reference instead (e.g. KASH_CHAIN=evm:${process.env['KASH_CHAIN_ID']} or KASH_CHAIN=solana:mainnet-beta) and unset KASH_CHAIN_ID.`\n );\n }\n\n let envChain: string | undefined;\n if (envChainRaw !== undefined) {\n envChain = normaliseChainInput(envChainRaw);\n if (envChain === undefined) {\n throw new CliConfigurationError(\n `KASH_CHAIN is not a chain reference: ${envChainRaw}`,\n 'Set KASH_CHAIN to solana:mainnet-beta, solana:devnet, evm:8453 (eip155:8453 is accepted too) or a numeric EVM chain id, or unset it to use the default.'\n );\n }\n }\n\n let envApiVersion: string | undefined;\n if (envApiVersionRaw !== undefined) {\n if (!apiVersionSchema.safeParse(envApiVersionRaw).success) {\n throw new CliConfigurationError(\n `KASH_API_VERSION is not a YYYY-MM-DD date: ${envApiVersionRaw}`,\n `Set KASH_API_VERSION to a dated API version such as ${DEFAULTS.apiVersion}, or unset it to use the default.`\n );\n }\n envApiVersion = envApiVersionRaw;\n }\n\n let envBundlerProvider: ResolvedConfig['bundlerProvider'];\n if (envBundlerProviderRaw !== undefined) {\n const allowed = ['flashbots', 'pimlico', 'alchemy', 'generic'] as const;\n if (!(allowed as readonly string[]).includes(envBundlerProviderRaw)) {\n throw new CliConfigurationError(\n `KASH_BUNDLER_PROVIDER must be one of ${allowed.join(', ')} (got \"${envBundlerProviderRaw}\").`,\n 'Unset the variable or set it to a supported preset.'\n );\n }\n envBundlerProvider = envBundlerProviderRaw as ResolvedConfig['bundlerProvider'];\n }\n\n const apiKey = envApiKey ?? profile.apiKey;\n // Resolution order for `baseUrl`:\n // 1. KASH_BASE_URL env var — always wins\n // 2. profile.baseUrl — explicit profile config\n // 3. inferred from apiKey prefix — kash_test_* → staging, kash_live_* → production\n // 4. DEFAULTS.baseUrl — production (final fallback)\n //\n // Step 3 mirrors `@kashdao/sdk`'s `inferBaseUrlFromApiKey()` so the\n // CLI and the SDK route the same key to the same environment without\n // requiring the user to configure two places. Without this, a user\n // with only a `kash_test_*` key would hit the production host until\n // they remembered to also set `--base-url`.\n const baseUrl =\n envBaseUrl ?? profile.baseUrl ?? inferBaseUrlFromApiKey(apiKey) ?? DEFAULTS.baseUrl;\n const defaultChain = envChain ?? profile.defaultChain ?? DEFAULTS.defaultChain;\n const apiVersion = envApiVersion ?? profile.apiVersion ?? DEFAULTS.apiVersion;\n const rpcUrl = envRpcUrl ?? profile.rpcUrl;\n const smartAccount = envSmartAccount ?? profile.smartAccount;\n const bundlerUrl = envBundlerUrl ?? profile.bundlerUrl;\n const bundlerProvider = envBundlerProvider ?? profile.bundlerProvider;\n const signerKeyRef = envSignerKeyRef ?? profile.signerKeyRef;\n // customChain has no env-var override — it's a structured object,\n // not a single string, and the right place to set it is `kash\n // config set customChain.<leaf>` so partial sets compose. CI use\n // cases that need a custom chain mount the config file directly\n // (KASH_CONFIG=...).\n const customChain = profile.customChain;\n\n return {\n apiKey,\n baseUrl,\n defaultChain,\n apiVersion,\n rpcUrl,\n smartAccount,\n bundlerUrl,\n bundlerProvider,\n signerKeyRef,\n customChain,\n profile: profileName,\n sources: {\n apiKey: envApiKey ? 'env' : profile.apiKey ? 'file' : 'unset',\n baseUrl: envBaseUrl\n ? 'env'\n : profile.baseUrl\n ? 'file'\n : inferBaseUrlFromApiKey(apiKey)\n ? 'inferred'\n : 'default',\n defaultChain:\n envChain !== undefined ? 'env' : profile.defaultChain !== undefined ? 'file' : 'default',\n apiVersion:\n envApiVersion !== undefined ? 'env' : profile.apiVersion !== undefined ? 'file' : 'default',\n profile: profileSource,\n rpcUrl: envRpcUrl ? 'env' : profile.rpcUrl ? 'file' : 'unset',\n smartAccount: envSmartAccount ? 'env' : profile.smartAccount ? 'file' : 'unset',\n bundlerUrl: envBundlerUrl ? 'env' : profile.bundlerUrl ? 'file' : 'unset',\n bundlerProvider: envBundlerProvider ? 'env' : profile.bundlerProvider ? 'file' : 'unset',\n signerKeyRef: envSignerKeyRef ? 'env' : profile.signerKeyRef ? 'file' : 'unset',\n customChain: profile.customChain ? 'file' : 'unset',\n },\n };\n}\n\nexport type WriteConfigOptions = {\n /** Profile to write to. Defaults to the current active profile. */\n readonly profile?: string;\n /** Override the config file path. */\n readonly configPath?: string;\n};\n\n/**\n * Result of {@link updateConfig} / {@link clearConfigField}. Carries\n * the resolved profile name so callers can render an accurate\n * \"wrote to profile X\" message instead of guessing — important for\n * the JSON contract that `kash auth set-key --json` ships, since\n * `--profile` may be unset and we want to report the actually-written\n * profile (which falls back to the file's `currentProfile`).\n */\nexport type UpdateConfigResult = {\n readonly profile: string;\n readonly stored: CliConfig;\n};\n\n/**\n * Mutate (and persist) a single field of the active (or named) profile.\n * Used by `auth set-key`, `auth logout`, `config set`. Writes the file\n * with `0600` permissions.\n */\nexport async function updateConfig(\n patch: Partial<CliConfig>,\n opts: WriteConfigOptions = {}\n): Promise<UpdateConfigResult> {\n const paths = resolveConfigPathsForOverride(opts.configPath);\n const file = await readFileConfig(paths);\n const profileName = opts.profile ?? file.currentProfile ?? DEFAULT_PROFILE;\n profileNameSchema.parse(profileName);\n const current = file.profiles[profileName] ?? {};\n const next = cliConfigSchema.parse({ ...current, ...patch });\n const updated: CliFile = {\n ...file,\n profiles: { ...file.profiles, [profileName]: next },\n };\n await writeFileConfig(paths, updated);\n return { profile: profileName, stored: next };\n}\n\n/** Wipe a single field from a profile (used by `auth logout`). */\nexport async function clearConfigField(\n field: keyof CliConfig,\n opts: WriteConfigOptions = {}\n): Promise<UpdateConfigResult> {\n const paths = resolveConfigPathsForOverride(opts.configPath);\n const file = await readFileConfig(paths);\n const profileName = opts.profile ?? file.currentProfile ?? DEFAULT_PROFILE;\n const current = file.profiles[profileName] ?? {};\n if (!(field in current)) return { profile: profileName, stored: current };\n const next = cliConfigSchema.parse(omitKey(current, field));\n const updated: CliFile = {\n ...file,\n profiles: { ...file.profiles, [profileName]: next },\n };\n await writeFileConfig(paths, updated);\n return { profile: profileName, stored: next };\n}\n\n/** List every profile name present in the config file. */\nexport async function listProfiles(\n opts: { configPath?: string } = {}\n): Promise<{ readonly current: string; readonly profiles: readonly string[] }> {\n const paths = resolveConfigPathsForOverride(opts.configPath);\n const file = await readFileConfig(paths);\n return {\n current: file.currentProfile ?? DEFAULT_PROFILE,\n profiles: Object.keys(file.profiles).sort(),\n };\n}\n\n/** Set the file's `currentProfile` field. Validates the name. */\nexport async function setCurrentProfile(\n name: string,\n opts: { configPath?: string } = {}\n): Promise<CliFile> {\n profileNameSchema.parse(name);\n const paths = resolveConfigPathsForOverride(opts.configPath);\n const file = await readFileConfig(paths);\n const updated: CliFile = { ...file, currentProfile: name };\n await writeFileConfig(paths, updated);\n return updated;\n}\n\n/** Remove a named profile. Refuses to remove the active one. */\nexport async function deleteProfile(\n name: string,\n opts: { configPath?: string } = {}\n): Promise<CliFile> {\n profileNameSchema.parse(name);\n const paths = resolveConfigPathsForOverride(opts.configPath);\n const file = await readFileConfig(paths);\n if (file.currentProfile === name) {\n throw new CliConfigurationError(\n `Cannot delete the active profile \"${name}\".`,\n 'Switch to another profile first with `kash config use <name>`.'\n );\n }\n if (!(name in file.profiles)) {\n return file;\n }\n const updated: CliFile = { ...file, profiles: omitKey(file.profiles, name) };\n await writeFileConfig(paths, updated);\n return updated;\n}\n\n/** Delete the entire config file. Used by `config reset`. */\nexport async function deleteConfig(opts: { configPath?: string } = {}): Promise<void> {\n const paths = resolveConfigPathsForOverride(opts.configPath);\n if (!existsSync(paths.file)) return;\n await unlink(paths.file);\n}\n\n/**\n * Return the full multi-profile file as-is. Used by `kash config\n * export` to dump every profile (vs `readConfig` which resolves a\n * single active profile). When the file doesn't exist, returns an\n * empty file shape so callers don't have to special-case \"no config\n * yet\".\n */\nexport async function readWholeFile(opts: { configPath?: string } = {}): Promise<CliFile> {\n const paths = resolveConfigPathsForOverride(opts.configPath);\n return await readFileConfig(paths);\n}\n\n/**\n * Replace the entire on-disk file with the supplied shape. Used by\n * `kash config import`. Validates against the `cliFileSchema` to\n * prevent garbage from landing on disk.\n *\n * Caller-side concerns (merge vs. overwrite, redaction policy, etc.)\n * are handled in the import command — this helper is pure persistence.\n */\nexport async function writeWholeFile(\n file: CliFile,\n opts: { configPath?: string } = {}\n): Promise<void> {\n const paths = resolveConfigPathsForOverride(opts.configPath);\n const validated = cliFileSchema.parse(file);\n await writeFileConfig(paths, validated);\n}\n\n/** Public re-export of the file-level schema for the import command. */\nexport { cliFileSchema };\n\nasync function writeFileConfig(paths: ConfigPaths, file: CliFile): Promise<void> {\n await ensureDir(paths.dir);\n // Use writeFile + chmod rather than writeFile({mode}) because the\n // mode flag only takes effect on first creation; rewrites would\n // keep the old (potentially looser) permissions.\n await writeFile(paths.file, JSON.stringify(file, null, 2), 'utf8');\n await chmodSafe(paths.file, 0o600);\n}\n\nasync function ensureDir(dir: string): Promise<void> {\n await mkdir(dir, { recursive: true, mode: 0o700 });\n await chmodSafe(dir, 0o700);\n}\n\nasync function chmodSafe(target: string, mode: number | undefined): Promise<void> {\n if (mode === undefined) return;\n if (process.platform === 'win32') return;\n try {\n await chmod(target, mode);\n } catch {\n // chmod can fail on some filesystems (e.g. mounted FAT volumes,\n // network shares). Treat as best-effort — the user's data still\n // landed, we just couldn't tighten perms.\n }\n}\n","/**\n * Chain references in the CLI.\n *\n * A profile names its chain with a chain reference rather than a numeric\n * chain id, because a number cannot name Solana — Kash's canonical chain since\n * the 2026-10-01 cutover. Parsing is `@kashdao/sdk`'s `tryParseChainRef`, so\n * the CLI and the SDK agree on what a reference is.\n *\n * Stored and printed in the spelling the API returns: `evm:<chainId>` and\n * `solana:<cluster>`. The CAIP-2 `eip155:<chainId>` and a bare legacy number\n * (`8453`, how 0.1.x stored it) are accepted on input and normalised to `evm:`.\n * Both directions go through the SDK (`tryParseChainRef` / `formatChainRef`),\n * so there is one implementation of what a reference is and how it is spelled.\n */\n\nimport { formatChainRef, tryParseChainRef } from '@kashdao/sdk';\n\n/**\n * Base mainnet. `kash protocol` and `kash eoa` drive the EVM protocol SDK\n * (ERC-4337 / viem) and fall back to it when the profile names a Solana chain.\n */\nconst BASE_MAINNET_CHAIN_ID = 8453;\n\nconst LEGACY_NUMERIC_CHAIN_ID = /^[1-9]\\d*$/;\n\n/**\n * Normalise user or file input to the API spelling (`evm:8453`,\n * `solana:devnet`), or `undefined` when it names no chain. Accepts\n * `solana:<cluster>`, `evm:<id>`, `eip155:<id>`, and a bare positive integer\n * as a legacy EVM chain id.\n */\nexport function normaliseChainInput(input: string): string | undefined {\n const value = input.trim();\n const ref = tryParseChainRef(LEGACY_NUMERIC_CHAIN_ID.test(value) ? `evm:${value}` : value);\n return ref === undefined ? undefined : formatChainRef(ref);\n}\n\n/**\n * The EVM chain id `kash protocol` / `kash eoa` run on: the profile's chain\n * when it is an EVM chain, otherwise Base mainnet. Those namespaces wrap the\n * EVM-only `@kashdao/protocol-sdk`, so a Solana default cannot drive them.\n */\nexport function protocolEvmChainId(defaultChain: string): number {\n const ref = tryParseChainRef(defaultChain);\n return ref?.type === 'evm' ? ref.chainId : BASE_MAINNET_CHAIN_ID;\n}\n\n/**\n * Whether the profile's chain is an EVM chain — the precondition for a\n * `customChain` block, which describes EVM contracts on an EVM network.\n */\nexport function isEvmChain(defaultChain: string): boolean {\n return tryParseChainRef(defaultChain)?.type === 'evm';\n}\n\n/**\n * How a market's chain is displayed: its `chainRef` (API version 2026-08-19)\n * or, on an older pin that sends only `chainId`, the equivalent `evm:<id>`.\n */\nexport function marketChainLabel(market: {\n readonly chainRef?: string | undefined;\n readonly chainId?: number | undefined;\n}): string {\n if (market.chainRef !== undefined) return market.chainRef;\n if (market.chainId !== undefined) return `evm:${market.chainId}`;\n return '(unknown)';\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
buildClient
|
|
4
|
+
} from "./chunk-H2QGFDZP.js";
|
|
5
|
+
import "./chunk-ZSMI63N3.js";
|
|
6
|
+
import "./chunk-2SR77BYA.js";
|
|
7
|
+
import "./chunk-6QSTFU4R.js";
|
|
8
|
+
import "./chunk-2HFKULGG.js";
|
|
9
|
+
import "./chunk-VFBQVUL4.js";
|
|
10
|
+
import "./chunk-WL7XUYPH.js";
|
|
11
|
+
export {
|
|
12
|
+
buildClient
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=client-REDY6K7J.js.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
log
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-2HFKULGG.js";
|
|
5
|
+
import "./chunk-VFBQVUL4.js";
|
|
6
6
|
import {
|
|
7
7
|
CliError
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-WL7XUYPH.js";
|
|
9
9
|
|
|
10
10
|
// src/completion.ts
|
|
11
11
|
import { Command } from "commander";
|
|
@@ -97,4 +97,4 @@ export {
|
|
|
97
97
|
createCompletionCommand,
|
|
98
98
|
initCompletion
|
|
99
99
|
};
|
|
100
|
-
//# sourceMappingURL=completion-
|
|
100
|
+
//# sourceMappingURL=completion-MXTJYK3D.js.map
|
|
@@ -2,36 +2,38 @@
|
|
|
2
2
|
import {
|
|
3
3
|
createTable,
|
|
4
4
|
redact
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-6UU43MF5.js";
|
|
6
6
|
import {
|
|
7
7
|
cliConfigSchema,
|
|
8
8
|
cliFileSchema,
|
|
9
9
|
deleteConfig,
|
|
10
10
|
deleteProfile,
|
|
11
11
|
listProfiles,
|
|
12
|
+
migrateFileShape,
|
|
13
|
+
normaliseChainInput,
|
|
12
14
|
readConfig,
|
|
13
15
|
readWholeFile,
|
|
14
16
|
resolveConfigPathsForOverride,
|
|
15
17
|
setCurrentProfile,
|
|
16
18
|
updateConfig,
|
|
17
19
|
writeWholeFile
|
|
18
|
-
} from "./chunk-
|
|
19
|
-
import "./chunk-
|
|
20
|
+
} from "./chunk-ZSMI63N3.js";
|
|
21
|
+
import "./chunk-2SR77BYA.js";
|
|
20
22
|
import {
|
|
21
23
|
readGlobals
|
|
22
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-AROIP4EQ.js";
|
|
23
25
|
import {
|
|
24
26
|
log,
|
|
25
27
|
print,
|
|
26
28
|
printJson,
|
|
27
29
|
style
|
|
28
|
-
} from "./chunk-
|
|
29
|
-
import "./chunk-
|
|
30
|
+
} from "./chunk-2HFKULGG.js";
|
|
31
|
+
import "./chunk-VFBQVUL4.js";
|
|
30
32
|
import {
|
|
31
33
|
CliError,
|
|
32
34
|
CliValidationError,
|
|
33
35
|
toCliError
|
|
34
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-WL7XUYPH.js";
|
|
35
37
|
|
|
36
38
|
// src/commands/config/index.ts
|
|
37
39
|
import { Command as Command9 } from "commander";
|
|
@@ -219,7 +221,7 @@ function parseAndValidate(raw) {
|
|
|
219
221
|
cause
|
|
220
222
|
});
|
|
221
223
|
}
|
|
222
|
-
const result = cliFileSchema.safeParse(parsed);
|
|
224
|
+
const result = cliFileSchema.safeParse(migrateFileShape(parsed));
|
|
223
225
|
if (!result.success) {
|
|
224
226
|
const first = result.error.issues[0];
|
|
225
227
|
throw new CliError(
|
|
@@ -372,7 +374,8 @@ var TOP_LEVEL_KEYS = [
|
|
|
372
374
|
// Kash-orchestrated
|
|
373
375
|
"apiKey",
|
|
374
376
|
"baseUrl",
|
|
375
|
-
"
|
|
377
|
+
"apiVersion",
|
|
378
|
+
"defaultChain",
|
|
376
379
|
// Direct mode
|
|
377
380
|
"rpcUrl",
|
|
378
381
|
"smartAccount",
|
|
@@ -407,7 +410,12 @@ var setConfigCommand = new Command6("set").description("Set a single config fiel
|
|
|
407
410
|
`
|
|
408
411
|
Examples:
|
|
409
412
|
$ kash config set baseUrl https://api-staging.kash.bot/v1 --profile staging
|
|
410
|
-
$ kash config set
|
|
413
|
+
$ kash config set defaultChain solana:devnet --profile staging
|
|
414
|
+
$ kash config set apiVersion 2026-08-19
|
|
415
|
+
|
|
416
|
+
Direct-mode commands (kash protocol / kash eoa) are EVM/Base only. They run on
|
|
417
|
+
defaultChain when it is an evm chain, and on Base mainnet otherwise:
|
|
418
|
+
$ kash config set defaultChain evm:84532 --profile mm # Base Sepolia
|
|
411
419
|
|
|
412
420
|
Direct-mode (kash protocol \u2026):
|
|
413
421
|
$ kash config set rpcUrl https://base-mainnet.g.alchemy.com/v2/... --profile mm
|
|
@@ -416,7 +424,7 @@ Direct-mode (kash protocol \u2026):
|
|
|
416
424
|
$ kash config set bundlerProvider flashbots --profile mm
|
|
417
425
|
|
|
418
426
|
Custom chain (local Anvil / forks / sidechains, bypasses static registry):
|
|
419
|
-
$ kash config set
|
|
427
|
+
$ kash config set defaultChain evm:31337 --profile anvil
|
|
420
428
|
$ kash config set rpcUrl http://localhost:8545 --profile anvil
|
|
421
429
|
$ kash config set customChain.name "Anvil local" --profile anvil
|
|
422
430
|
$ kash config set customChain.factoryAddress 0xCf7Ed... --profile anvil
|
|
@@ -485,6 +493,7 @@ function buildTopLevelPatch(key, value) {
|
|
|
485
493
|
switch (key) {
|
|
486
494
|
case "apiKey":
|
|
487
495
|
case "baseUrl":
|
|
496
|
+
case "apiVersion":
|
|
488
497
|
case "rpcUrl":
|
|
489
498
|
case "smartAccount":
|
|
490
499
|
case "bundlerUrl":
|
|
@@ -494,18 +503,16 @@ function buildTopLevelPatch(key, value) {
|
|
|
494
503
|
cliConfigSchema.parse(candidate);
|
|
495
504
|
return candidate;
|
|
496
505
|
}
|
|
497
|
-
case "
|
|
498
|
-
const
|
|
499
|
-
if (
|
|
506
|
+
case "defaultChain": {
|
|
507
|
+
const defaultChain = normaliseChainInput(value);
|
|
508
|
+
if (defaultChain === void 0) {
|
|
500
509
|
throw new CliValidationError(
|
|
501
|
-
"
|
|
502
|
-
|
|
503
|
-
"
|
|
510
|
+
`"${value}" is not a chain reference.`,
|
|
511
|
+
"Use solana:mainnet-beta, solana:devnet, evm:<chainId> (e.g. evm:8453; eip155:8453 is accepted too), or a numeric EVM chain id.",
|
|
512
|
+
"defaultChain"
|
|
504
513
|
);
|
|
505
514
|
}
|
|
506
|
-
|
|
507
|
-
cliConfigSchema.parse(candidate);
|
|
508
|
-
return candidate;
|
|
515
|
+
return { defaultChain };
|
|
509
516
|
}
|
|
510
517
|
}
|
|
511
518
|
}
|
|
@@ -559,7 +566,8 @@ Examples:
|
|
|
559
566
|
authenticated: Boolean(config.apiKey),
|
|
560
567
|
apiKey: config.apiKey ? redact(config.apiKey) : null,
|
|
561
568
|
baseUrl: config.baseUrl,
|
|
562
|
-
|
|
569
|
+
apiVersion: config.apiVersion,
|
|
570
|
+
defaultChain: config.defaultChain,
|
|
563
571
|
rpcUrl: config.rpcUrl ?? null,
|
|
564
572
|
smartAccount: config.smartAccount ?? null,
|
|
565
573
|
bundlerUrl: config.bundlerUrl ?? null,
|
|
@@ -576,8 +584,9 @@ Examples:
|
|
|
576
584
|
` ${style.dim("API key ")} ${config.apiKey ? redact(config.apiKey) : "(unset)"} (${config.sources.apiKey})`
|
|
577
585
|
);
|
|
578
586
|
print(` ${style.dim("Base URL ")} ${config.baseUrl} (${config.sources.baseUrl})`);
|
|
587
|
+
print(` ${style.dim("API version ")} ${config.apiVersion} (${config.sources.apiVersion})`);
|
|
579
588
|
print(
|
|
580
|
-
` ${style.dim("Default chain ")} ${
|
|
589
|
+
` ${style.dim("Default chain ")} ${config.defaultChain} (${config.sources.defaultChain})`
|
|
581
590
|
);
|
|
582
591
|
const hasDirectMode = config.rpcUrl !== void 0 || config.smartAccount !== void 0 || config.bundlerUrl !== void 0 || config.bundlerProvider !== void 0 || config.signerKeyRef !== void 0;
|
|
583
592
|
if (hasDirectMode) {
|
|
@@ -687,4 +696,4 @@ var configCommand = new Command9("config").description("Inspect and edit ~/.kash
|
|
|
687
696
|
export {
|
|
688
697
|
configCommand
|
|
689
698
|
};
|
|
690
|
-
//# sourceMappingURL=config-
|
|
699
|
+
//# sourceMappingURL=config-TIJXUJ5N.js.map
|