@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.
Files changed (85) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/CONTRIBUTING.md +159 -0
  3. package/LICENSE +21 -0
  4. package/README.md +868 -0
  5. package/SECURITY.md +110 -0
  6. package/dist/account-AVFLEM5D.js +90 -0
  7. package/dist/account-AVFLEM5D.js.map +1 -0
  8. package/dist/auth-GUJCVKTD.js +239 -0
  9. package/dist/auth-GUJCVKTD.js.map +1 -0
  10. package/dist/chunk-BN2CUM42.js +9 -0
  11. package/dist/chunk-BN2CUM42.js.map +1 -0
  12. package/dist/chunk-BRK7KJ4O.js +154 -0
  13. package/dist/chunk-BRK7KJ4O.js.map +1 -0
  14. package/dist/chunk-KMBMQIZ7.js +393 -0
  15. package/dist/chunk-KMBMQIZ7.js.map +1 -0
  16. package/dist/chunk-LBIRQHX5.js +133 -0
  17. package/dist/chunk-LBIRQHX5.js.map +1 -0
  18. package/dist/chunk-MIXOZU2S.js +366 -0
  19. package/dist/chunk-MIXOZU2S.js.map +1 -0
  20. package/dist/chunk-QJMF73M5.js +129 -0
  21. package/dist/chunk-QJMF73M5.js.map +1 -0
  22. package/dist/chunk-UZNSYATZ.js +680 -0
  23. package/dist/chunk-UZNSYATZ.js.map +1 -0
  24. package/dist/chunk-VIADBYFY.js +94 -0
  25. package/dist/chunk-VIADBYFY.js.map +1 -0
  26. package/dist/chunk-YHCG2SUC.js +159 -0
  27. package/dist/chunk-YHCG2SUC.js.map +1 -0
  28. package/dist/chunk-YJX3JJ4M.js +174 -0
  29. package/dist/chunk-YJX3JJ4M.js.map +1 -0
  30. package/dist/client-IOM55ZCS.js +14 -0
  31. package/dist/client-IOM55ZCS.js.map +1 -0
  32. package/dist/completion-ZZGX5BQC.js +100 -0
  33. package/dist/completion-ZZGX5BQC.js.map +1 -0
  34. package/dist/config-XJL5TSYK.js +690 -0
  35. package/dist/config-XJL5TSYK.js.map +1 -0
  36. package/dist/config-store-3ZSYGXMQ.js +44 -0
  37. package/dist/config-store-3ZSYGXMQ.js.map +1 -0
  38. package/dist/docs-MDKKSJDC.js +102 -0
  39. package/dist/docs-MDKKSJDC.js.map +1 -0
  40. package/dist/eoa-IQ72EIHR.js +551 -0
  41. package/dist/eoa-IQ72EIHR.js.map +1 -0
  42. package/dist/errors-WMZIEGQI.js +18 -0
  43. package/dist/errors-WMZIEGQI.js.map +1 -0
  44. package/dist/explain-H4EH3KH3.js +165 -0
  45. package/dist/explain-H4EH3KH3.js.map +1 -0
  46. package/dist/global-options-XOLJUPTT.js +18 -0
  47. package/dist/global-options-XOLJUPTT.js.map +1 -0
  48. package/dist/health-VZEIII74.js +98 -0
  49. package/dist/health-VZEIII74.js.map +1 -0
  50. package/dist/help-footer-GTANVDNP.js +43 -0
  51. package/dist/help-footer-GTANVDNP.js.map +1 -0
  52. package/dist/index.d.ts +2 -0
  53. package/dist/index.js +251 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/intro-PQQTYWR7.js +41 -0
  56. package/dist/intro-PQQTYWR7.js.map +1 -0
  57. package/dist/markets-C37JZDPE.js +295 -0
  58. package/dist/markets-C37JZDPE.js.map +1 -0
  59. package/dist/output-VCBZ3FM7.js +22 -0
  60. package/dist/output-VCBZ3FM7.js.map +1 -0
  61. package/dist/portfolio-2AEPIJIG.js +115 -0
  62. package/dist/portfolio-2AEPIJIG.js.map +1 -0
  63. package/dist/protocol-XEQXF2GW.js +1572 -0
  64. package/dist/protocol-XEQXF2GW.js.map +1 -0
  65. package/dist/quote-I4DVJ7ZB.js +144 -0
  66. package/dist/quote-I4DVJ7ZB.js.map +1 -0
  67. package/dist/schema-PIFQ65TS.js +410 -0
  68. package/dist/schema-PIFQ65TS.js.map +1 -0
  69. package/dist/setup-USZ6IODD.js +260 -0
  70. package/dist/setup-USZ6IODD.js.map +1 -0
  71. package/dist/stdin-YW2CEQXU.js +28 -0
  72. package/dist/stdin-YW2CEQXU.js.map +1 -0
  73. package/dist/trace-IZBYTUFO.js +103 -0
  74. package/dist/trace-IZBYTUFO.js.map +1 -0
  75. package/dist/trade-IIZSEXEI.js +586 -0
  76. package/dist/trade-IIZSEXEI.js.map +1 -0
  77. package/dist/version-JDK3PEP5.js +117 -0
  78. package/dist/version-JDK3PEP5.js.map +1 -0
  79. package/dist/version-check-TDCION37.js +138 -0
  80. package/dist/version-check-TDCION37.js.map +1 -0
  81. package/dist/webhooks-PTVRKICZ.js +680 -0
  82. package/dist/webhooks-PTVRKICZ.js.map +1 -0
  83. package/dist/with-retry-4FIZG3A7.js +223 -0
  84. package/dist/with-retry-4FIZG3A7.js.map +1 -0
  85. package/package.json +99 -0
@@ -0,0 +1,551 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ loadRawPrivateKey,
4
+ resolveCliCustomChain
5
+ } from "./chunk-YJX3JJ4M.js";
6
+ import {
7
+ formatAddress,
8
+ formatGwei,
9
+ formatUsdcAtomic
10
+ } from "./chunk-BRK7KJ4O.js";
11
+ import {
12
+ readConfig
13
+ } from "./chunk-KMBMQIZ7.js";
14
+ import {
15
+ DEFAULT_SLIPPAGE_BPS,
16
+ MAX_UINT256,
17
+ decimalToAtomicUsdc,
18
+ decimalToAtomicWad,
19
+ extractPartialHash,
20
+ parseDeadlineSec,
21
+ parseOutcomeIndex,
22
+ parseSlippageBps,
23
+ parseUppercaseSide,
24
+ validateAddress,
25
+ validateAddressOptional
26
+ } from "./chunk-YHCG2SUC.js";
27
+ import {
28
+ parseOptionalPositiveFloat,
29
+ parseOptionalPositiveInt,
30
+ parsePositiveInt,
31
+ readGlobals
32
+ } from "./chunk-LBIRQHX5.js";
33
+ import {
34
+ log,
35
+ print,
36
+ printJson,
37
+ style
38
+ } from "./chunk-VIADBYFY.js";
39
+ import "./chunk-MIXOZU2S.js";
40
+ import {
41
+ CliError,
42
+ CliValidationError,
43
+ EXIT_CODES,
44
+ toCliError
45
+ } from "./chunk-UZNSYATZ.js";
46
+
47
+ // src/commands/eoa/index.ts
48
+ import { Command } from "commander";
49
+
50
+ // src/utils/eoa-client.ts
51
+ async function buildEoaClient(opts) {
52
+ const globals = opts.globals;
53
+ const config = await readConfig({
54
+ ...globals?.profile === void 0 ? {} : { profile: globals.profile },
55
+ ...globals?.configPath === void 0 ? {} : { configPath: globals.configPath }
56
+ });
57
+ const rpc = globals?.baseUrl ?? config.rpcUrl;
58
+ if (!rpc) {
59
+ throw missingEoaConfig("rpcUrl", "--rpc-url or `kash config set rpcUrl <url>`");
60
+ }
61
+ if (!config.signerKeyRef) {
62
+ throw missingEoaConfig(
63
+ "signerKeyRef",
64
+ "`kash config set signerKeyRef file:<path>` or `env:<NAME>` (CLI never persists raw keys)"
65
+ );
66
+ }
67
+ const { createEoaClient } = await import("@kashdao/protocol-sdk");
68
+ const signer = await loadEoaSigner(config.signerKeyRef);
69
+ const customChain = await maybeBuildCustomChain(config, rpc);
70
+ const client = createEoaClient({
71
+ chainId: config.defaultChainId,
72
+ rpc,
73
+ signer,
74
+ ...customChain === void 0 ? {} : { customChain }
75
+ });
76
+ return {
77
+ client,
78
+ chainId: config.defaultChainId,
79
+ account: signer.ownerAddress
80
+ };
81
+ }
82
+ async function loadEoaSigner(ref) {
83
+ const rawKey = await loadRawPrivateKey(ref);
84
+ const [{ privateKeyToAccount }, { viemAccountEoaSigner }] = await Promise.all([
85
+ import("viem/accounts"),
86
+ import("@kashdao/protocol-sdk")
87
+ ]);
88
+ return viemAccountEoaSigner(privateKeyToAccount(rawKey));
89
+ }
90
+ async function maybeBuildCustomChain(config, rpc) {
91
+ if (config.customChain === void 0) return void 0;
92
+ if (config.defaultChainId === void 0) {
93
+ throw missingEoaConfig(
94
+ "defaultChainId",
95
+ "`kash config set defaultChainId <id>` (required when customChain is set so the CLI can construct the viem chain)"
96
+ );
97
+ }
98
+ return resolveCliCustomChain({
99
+ customChain: config.customChain,
100
+ chainId: config.defaultChainId,
101
+ rpc
102
+ });
103
+ }
104
+ function missingEoaConfig(field, hint) {
105
+ return new CliError(`EOA-mode config missing: ${field}.`, {
106
+ code: "DIRECT_CONFIG_MISSING",
107
+ exitCode: EXIT_CODES.GENERIC,
108
+ suggestion: `Set ${field} via ${hint}.`,
109
+ actions: [
110
+ {
111
+ type: "check_input",
112
+ field,
113
+ description: hint
114
+ }
115
+ ]
116
+ });
117
+ }
118
+
119
+ // src/commands/eoa/index.ts
120
+ var balanceCommand = new Command("balance").description(
121
+ "Read on-chain USDC + native gas balances for the EOA (defaults to signer's address)."
122
+ ).argument("[account]", "address to read (default: signer's ownerAddress)").action(async (account, _opts, cmd) => {
123
+ const globals = readGlobals(cmd);
124
+ const accountAddress = validateAddressOptional(account, "account");
125
+ try {
126
+ const resolved = await buildEoaClient({ globals });
127
+ const target = accountAddress ?? resolved.account;
128
+ const [usdc, gas] = await Promise.all([
129
+ resolved.client.account.usdcBalance(target),
130
+ resolved.client.account.gasBalance(target)
131
+ ]);
132
+ const payload = {
133
+ account: target,
134
+ chainId: resolved.chainId,
135
+ usdcAtomic: usdc.toString(),
136
+ gasWei: gas.toString()
137
+ };
138
+ if (globals.json) {
139
+ printJson(payload);
140
+ return;
141
+ }
142
+ print("");
143
+ print(` ${style.dim("Account ")} ${formatAddress(target, 10, 8)}`);
144
+ print(` ${style.dim("Chain ")} ${String(resolved.chainId)}`);
145
+ print(` ${style.dim("USDC ")} ${formatUsdcAtomic(usdc.toString())}`);
146
+ print(
147
+ ` ${style.dim("Gas ")} ${formatGwei(gas)} gwei ${style.dim(`(${gas.toString()} wei)`)}`
148
+ );
149
+ } catch (cause) {
150
+ throw toCliError(cause);
151
+ }
152
+ });
153
+ var marketCommand = new Command("market").description("Read on-chain market state (reserves, supplies, weights, derived probabilities).").argument("<address>", "market contract address (0x-prefixed)").action(async (address, _opts, cmd) => {
154
+ const globals = readGlobals(cmd);
155
+ const marketAddress = validateAddress(address, "address");
156
+ try {
157
+ const resolved = await buildEoaClient({ globals });
158
+ const state = await resolved.client.markets.state(marketAddress);
159
+ const payload = {
160
+ marketAddress: state.marketAddress,
161
+ chainId: resolved.chainId,
162
+ status: state.status,
163
+ readAt: state.readAt.toString(),
164
+ reserveWad: state.reserveWad.toString(),
165
+ outcomes: state.outcomes.map((o) => ({
166
+ index: o.index,
167
+ outstandingTokensWad: o.outstandingTokensWad.toString(),
168
+ weightWad: o.weightWad.toString(),
169
+ probability: o.probability
170
+ }))
171
+ };
172
+ if (globals.json) {
173
+ printJson(payload);
174
+ return;
175
+ }
176
+ print("");
177
+ print(` ${style.dim("Market ")} ${formatAddress(state.marketAddress, 10, 8)}`);
178
+ print(` ${style.dim("Status ")} ${state.status}`);
179
+ print(` ${style.dim("Outcomes ")} ${String(state.outcomes.length)}`);
180
+ print("");
181
+ for (const outcome of state.outcomes) {
182
+ const pct = (outcome.probability * 100).toFixed(2);
183
+ print(` [${String(outcome.index)}] p=${pct}%`);
184
+ }
185
+ } catch (cause) {
186
+ throw toCliError(cause);
187
+ }
188
+ });
189
+ var quoteCommand = new Command("quote").description("On-chain price quote for buying or selling an outcome.").argument("<address>", "market contract address").requiredOption("-s, --side <side>", "buy | sell").requiredOption("-o, --outcome <index>", "outcome index (0-based)").requiredOption("-a, --amount <decimal>", "USDC for buy / outcome tokens for sell").action(async (address, options, cmd) => {
190
+ const globals = readGlobals(cmd);
191
+ const marketAddress = validateAddress(address, "address");
192
+ const side = parseUppercaseSide(options.side);
193
+ const outcome = parseOutcomeIndex(options.outcome);
194
+ const amount = side === "BUY" ? decimalToAtomicUsdc(options.amount, "amount") : decimalToAtomicWad(options.amount, "amount");
195
+ try {
196
+ const resolved = await buildEoaClient({ globals });
197
+ const quote = await resolved.client.markets.quote(marketAddress, {
198
+ side,
199
+ outcome,
200
+ amount
201
+ });
202
+ const payload = {
203
+ side: quote.side,
204
+ outcomeIndex: quote.outcomeIndex,
205
+ amountIn: quote.amountIn.toString(),
206
+ amountOut: quote.amountOut.toString(),
207
+ reserveAfterWad: quote.reserveAfterWad.toString(),
208
+ pricesAfterWad: quote.pricesAfterWad.map((p) => p.toString())
209
+ };
210
+ if (globals.json) {
211
+ printJson(payload);
212
+ return;
213
+ }
214
+ print("");
215
+ print(` ${style.dim("Side ")} ${quote.side}`);
216
+ print(` ${style.dim("Outcome ")} ${String(quote.outcomeIndex)}`);
217
+ print(` ${style.dim("In ")} ${quote.amountIn.toString()}`);
218
+ print(` ${style.dim("Out ")} ${quote.amountOut.toString()}`);
219
+ } catch (cause) {
220
+ throw toCliError(cause);
221
+ }
222
+ });
223
+ var positionCommand = new Command("position").description("Read on-chain outcome-token holdings (ERC-1155) for a market.").argument("<market>", "market contract address (0x-prefixed)").argument("[account]", "address whose holdings to read (default: signer's)").action(async (market, account, _opts, cmd) => {
224
+ const globals = readGlobals(cmd);
225
+ const marketAddress = validateAddress(market, "market");
226
+ const accountAddress = validateAddressOptional(account, "account");
227
+ try {
228
+ const resolved = await buildEoaClient({ globals });
229
+ const target = accountAddress ?? resolved.account;
230
+ const position = await resolved.client.account.position(target, marketAddress);
231
+ const payload = {
232
+ account: target,
233
+ marketAddress: position.marketAddress,
234
+ chainId: resolved.chainId,
235
+ numOutcomes: position.numOutcomes,
236
+ holdings: position.holdings.map((h) => ({
237
+ outcomeIndex: h.outcomeIndex,
238
+ balanceWad: h.balanceWad.toString()
239
+ }))
240
+ };
241
+ if (globals.json) {
242
+ printJson(payload);
243
+ return;
244
+ }
245
+ print("");
246
+ print(` ${style.dim("Account ")} ${formatAddress(target, 10, 8)}`);
247
+ print(` ${style.dim("Market ")} ${formatAddress(position.marketAddress, 10, 8)}`);
248
+ print("");
249
+ for (const h of position.holdings) {
250
+ print(` [${String(h.outcomeIndex)}] balance=${h.balanceWad.toString()} (WAD)`);
251
+ }
252
+ } catch (cause) {
253
+ throw toCliError(cause);
254
+ }
255
+ });
256
+ var allowanceCommand = new Command("allowance").description("Read the on-chain USDC allowance from `account` to `spender`.").argument("<spender>", "spender contract address").argument("[account]", "owner address (default: signer's)").action(async (spender, account, _opts, cmd) => {
257
+ const globals = readGlobals(cmd);
258
+ const spenderAddress = validateAddress(spender, "spender");
259
+ const accountAddress = validateAddressOptional(account, "account");
260
+ try {
261
+ const resolved = await buildEoaClient({ globals });
262
+ const owner = accountAddress ?? resolved.account;
263
+ const allowance = await resolved.client.account.usdcAllowance(owner, spenderAddress);
264
+ const payload = {
265
+ owner,
266
+ spender,
267
+ chainId: resolved.chainId,
268
+ allowanceAtomic: allowance.toString()
269
+ };
270
+ if (globals.json) {
271
+ printJson(payload);
272
+ return;
273
+ }
274
+ print("");
275
+ print(` ${style.dim("Owner ")} ${formatAddress(owner, 10, 8)}`);
276
+ print(` ${style.dim("Spender ")} ${formatAddress(spender, 10, 8)}`);
277
+ print(` ${style.dim("Allowance")} ${formatUsdcAtomic(allowance.toString())}`);
278
+ } catch (cause) {
279
+ throw toCliError(cause);
280
+ }
281
+ });
282
+ var feesCommand = new Command("fees").description("EIP-1559 fee estimate for the configured chain.").option("--blocks <n>", "number of recent blocks to sample (default 4)").option("--percentile <n>", "priority-fee percentile per block (1-99, default 50)").option("--base-multiplier <n>", "multiplier on predicted next-block base fee (default 2.0)").option("--priority-floor-gwei <n>", "floor for maxPriorityFeePerGas in gwei (default 1)").action(
283
+ async (options, cmd) => {
284
+ const globals = readGlobals(cmd);
285
+ const blocks = parseOptionalPositiveInt(options.blocks, "blocks");
286
+ const percentile = parseOptionalPositiveInt(options.percentile, "percentile");
287
+ if (percentile !== void 0 && (percentile < 1 || percentile > 99)) {
288
+ throw new CliValidationError("--percentile must be between 1 and 99.");
289
+ }
290
+ const baseMultiplier = parseOptionalPositiveFloat(options.baseMultiplier, "base-multiplier");
291
+ const priorityFloorGwei = parseOptionalPositiveInt(
292
+ options.priorityFloorGwei,
293
+ "priority-floor-gwei"
294
+ );
295
+ try {
296
+ const resolved = await buildEoaClient({ globals });
297
+ const estimate = await resolved.client.estimateFees({
298
+ ...blocks === void 0 ? {} : { blockCount: blocks },
299
+ ...percentile === void 0 ? {} : { rewardPercentile: percentile },
300
+ ...baseMultiplier === void 0 ? {} : { baseMultiplier },
301
+ ...priorityFloorGwei === void 0 ? {} : { priorityFeeFloorWei: BigInt(priorityFloorGwei) * 10n ** 9n }
302
+ });
303
+ const payload = {
304
+ chainId: resolved.chainId,
305
+ maxFeePerGas: estimate.maxFeePerGas.toString(),
306
+ maxPriorityFeePerGas: estimate.maxPriorityFeePerGas.toString()
307
+ };
308
+ if (globals.json) {
309
+ printJson(payload);
310
+ return;
311
+ }
312
+ print("");
313
+ print(
314
+ ` ${style.dim("maxFee ")} ${formatGwei(estimate.maxFeePerGas)} gwei (${estimate.maxFeePerGas.toString()} wei)`
315
+ );
316
+ print(
317
+ ` ${style.dim("maxPrio ")} ${formatGwei(estimate.maxPriorityFeePerGas)} gwei (${estimate.maxPriorityFeePerGas.toString()} wei)`
318
+ );
319
+ } catch (cause) {
320
+ throw toCliError(cause);
321
+ }
322
+ }
323
+ );
324
+ var tradeBuyCommand = new Command("buy").description("One-shot BUY (EIP-1559 tx, signed locally and submitted to chain).").argument("<market>", "market contract address").requiredOption("-o, --outcome <index>", "outcome index (0-based)").requiredOption("-a, --amount <usdc>", "USDC to spend (decimal)").option("--slippage-bps <n>", "slippage tolerance in bps (default 50)").option("--deadline-sec <n>", "unix-seconds deadline (default now + 5min)").option("--dry-run", "prepare + simulate but DO NOT sign or submit").option("--no-simulate", "skip eth_call preflight").option("--no-wait", "fire-and-forget: return tx hash without waiting for inclusion").option("--wait-timeout-ms <n>", "cap on the receipt wait (default 60000)").action(
325
+ async (market, options, cmd) => {
326
+ await runTrade("buy", market, options, cmd);
327
+ }
328
+ );
329
+ var tradeSellCommand = new Command("sell").description("One-shot SELL.").argument("<market>", "market contract address").requiredOption("-o, --outcome <index>", "outcome index (0-based)").requiredOption("-t, --tokens <amount>", "outcome tokens to sell (WAD decimal)").option("--slippage-bps <n>", "slippage tolerance in bps (default 50)").option("--deadline-sec <n>", "unix-seconds deadline (default now + 5min)").option("--dry-run", "prepare + simulate but DO NOT sign or submit").option("--no-simulate", "skip eth_call preflight").option("--no-wait", "fire-and-forget").option("--wait-timeout-ms <n>", "cap on the receipt wait (default 60000)").action(
330
+ async (market, options, cmd) => {
331
+ await runTrade("sell", market, options, cmd);
332
+ }
333
+ );
334
+ var tradeCloseCommand = new Command("close").description("Sell the entire EOA balance for an outcome.").argument("<market>", "market contract address").requiredOption("-o, --outcome <index>", "outcome index (0-based)").option("--slippage-bps <n>", "slippage tolerance in bps (default 50)").option("--deadline-sec <n>", "unix-seconds deadline (default now + 5min)").option("--dry-run", "prepare + simulate but DO NOT sign or submit").option("--no-simulate", "skip eth_call preflight").option("--no-wait", "fire-and-forget").option("--wait-timeout-ms <n>", "cap on the receipt wait (default 60000)").action(async (market, options, cmd) => {
335
+ await runTrade("close", market, options, cmd);
336
+ });
337
+ var tradeApproveCommand = new Command("approve").description("USDC approval \u2014 required once before the first BUY.").argument("<spender>", "spender contract address (typically a Market)").option("-a, --amount <usdc>", "atomic-USDC amount (default unlimited)").option("--dry-run", "prepare + simulate but DO NOT sign or submit").option("--no-simulate", "skip eth_call preflight").option("--no-wait", "fire-and-forget").option("--wait-timeout-ms <n>", "cap on the receipt wait (default 60000)").action(
338
+ async (spender, options, cmd) => {
339
+ const globals = readGlobals(cmd);
340
+ const spenderAddress = validateAddress(spender, "spender");
341
+ const amount = options.amount ? decimalToAtomicUsdc(options.amount, "amount") : MAX_UINT256;
342
+ const waitTimeoutMs = options.waitTimeoutMs ? parsePositiveInt(options.waitTimeoutMs, "wait-timeout-ms") : void 0;
343
+ try {
344
+ const resolved = await buildEoaClient({ globals });
345
+ const params = {
346
+ account: resolved.account,
347
+ spender: spenderAddress,
348
+ amount
349
+ };
350
+ if (options.dryRun === true) {
351
+ const built = await resolved.client.trades.prepareApprove(params, {
352
+ simulate: options.simulate !== false
353
+ });
354
+ emitDryRun("approve", spender, built, globals.json);
355
+ return;
356
+ }
357
+ const sendOptions = {
358
+ simulate: options.simulate !== false,
359
+ wait: options.wait !== false,
360
+ ...waitTimeoutMs === void 0 ? {} : { waitTimeoutMs }
361
+ };
362
+ let result;
363
+ try {
364
+ result = await resolved.client.trades.send.approve(params, sendOptions);
365
+ } catch (cause) {
366
+ const partialHash = extractPartialTransactionHash(cause);
367
+ if (partialHash !== void 0) {
368
+ if (globals.json) {
369
+ printJson({ transactionHash: partialHash, waited: false, partial: true });
370
+ } else {
371
+ log.warn(
372
+ `Submit succeeded but wait timed out. The approve tx is on-chain \u2014 check inclusion via your block explorer for: ${partialHash}`
373
+ );
374
+ }
375
+ }
376
+ throw cause;
377
+ }
378
+ emitSendResult("approve", spender, result, globals.json);
379
+ } catch (cause) {
380
+ throw toCliError(cause);
381
+ }
382
+ }
383
+ );
384
+ var tradeCommand = new Command("trade").description("Direct-mode trade execution (vanilla EIP-1559 tx, signed locally).").addHelpText(
385
+ "after",
386
+ `
387
+ Wait controls \u2014 surface parity with \`kash protocol trade\`:
388
+ --wait-timeout-ms <n> Cap on the receipt wait (supported).
389
+ --wait-interval-ms NOT exposed in EOA mode. viem's
390
+ \`waitForTransactionReceipt\` controls its
391
+ own polling cadence based on chain block
392
+ time; the EOA SDK does not pass through a
393
+ custom interval. Use SA mode
394
+ (\`kash protocol trade\`) if you need
395
+ fine-grained interval control.
396
+ `
397
+ ).addCommand(tradeBuyCommand).addCommand(tradeSellCommand).addCommand(tradeCloseCommand).addCommand(tradeApproveCommand);
398
+ var eoaCommand = new Command("eoa").description(
399
+ "Self-orchestrated direct-to-chain operations using a vanilla EOA (no smart account). Like every Kash entry point, this path is non-custodial."
400
+ ).addCommand(balanceCommand).addCommand(marketCommand).addCommand(quoteCommand).addCommand(positionCommand).addCommand(allowanceCommand).addCommand(feesCommand).addCommand(tradeCommand);
401
+ async function runTrade(side, market, options, cmd) {
402
+ const globals = readGlobals(cmd);
403
+ const marketAddress = validateAddress(market, "market");
404
+ const outcome = parseOutcomeIndex(options.outcome);
405
+ const slippageBps = options.slippageBps ? parseSlippageBps(options.slippageBps) : DEFAULT_SLIPPAGE_BPS;
406
+ const deadline = options.deadlineSec ? parseDeadlineSec(options.deadlineSec) : void 0;
407
+ const waitTimeoutMs = options.waitTimeoutMs ? parsePositiveInt(options.waitTimeoutMs, "wait-timeout-ms") : void 0;
408
+ let amountUsdc;
409
+ let amountTokens;
410
+ if (side === "buy") {
411
+ amountUsdc = decimalToAtomicUsdc(options.amount, "amount");
412
+ } else if (side === "sell") {
413
+ amountTokens = decimalToAtomicWad(options.tokens, "tokens");
414
+ }
415
+ try {
416
+ const resolved = await buildEoaClient({ globals });
417
+ const baseParams = {
418
+ account: resolved.account,
419
+ smartAccount: resolved.account,
420
+ outcome,
421
+ maxSlippageBps: slippageBps,
422
+ ...deadline === void 0 ? {} : { deadline }
423
+ };
424
+ const opts = { simulate: options.simulate !== false };
425
+ if (options.dryRun === true) {
426
+ let built;
427
+ if (side === "buy") {
428
+ built = await resolved.client.trades.prepareBuy(
429
+ marketAddress,
430
+ { ...baseParams, amountUsdc },
431
+ opts
432
+ );
433
+ } else if (side === "sell") {
434
+ built = await resolved.client.trades.prepareSell(
435
+ marketAddress,
436
+ { ...baseParams, amountTokens },
437
+ opts
438
+ );
439
+ } else {
440
+ built = await resolved.client.trades.prepareClosePosition(marketAddress, baseParams, opts);
441
+ }
442
+ emitDryRun(side, market, built, globals.json);
443
+ return;
444
+ }
445
+ const sendOptions = {
446
+ simulate: options.simulate !== false,
447
+ wait: options.wait !== false,
448
+ ...waitTimeoutMs === void 0 ? {} : { waitTimeoutMs }
449
+ };
450
+ let result;
451
+ try {
452
+ if (side === "buy") {
453
+ result = await resolved.client.trades.send.buy(
454
+ marketAddress,
455
+ { ...baseParams, amountUsdc },
456
+ sendOptions
457
+ );
458
+ } else if (side === "sell") {
459
+ result = await resolved.client.trades.send.sell(
460
+ marketAddress,
461
+ { ...baseParams, amountTokens },
462
+ sendOptions
463
+ );
464
+ } else {
465
+ result = await resolved.client.trades.send.closePosition(
466
+ marketAddress,
467
+ baseParams,
468
+ sendOptions
469
+ );
470
+ }
471
+ } catch (cause) {
472
+ const partialHash = extractPartialTransactionHash(cause);
473
+ if (partialHash !== void 0) {
474
+ if (globals.json) {
475
+ printJson({ transactionHash: partialHash, waited: false, partial: true });
476
+ } else {
477
+ log.warn(
478
+ `Submit succeeded but wait timed out. The tx is on-chain \u2014 check inclusion via your block explorer for: ${partialHash}`
479
+ );
480
+ }
481
+ }
482
+ throw cause;
483
+ }
484
+ emitSendResult(side, market, result, globals.json);
485
+ } catch (cause) {
486
+ throw toCliError(cause);
487
+ }
488
+ }
489
+ function extractPartialTransactionHash(cause) {
490
+ return extractPartialHash(cause, {
491
+ code: "WAIT_RECEIPT_FAILED",
492
+ contextKey: "transactionHash"
493
+ });
494
+ }
495
+ function emitDryRun(side, target, built, json) {
496
+ if (json) {
497
+ printJson({
498
+ side,
499
+ target,
500
+ transaction: built.transaction,
501
+ transactionHash: built.transactionHash,
502
+ dryRun: true
503
+ });
504
+ return;
505
+ }
506
+ print("");
507
+ print(` ${style.bold("Dry run")} \u2014 transaction prepared but NOT signed/submitted.`);
508
+ print(` ${style.dim("Side ")} ${side}`);
509
+ print(` ${style.dim("Target")} ${formatAddress(target, 10, 8)}`);
510
+ print(` ${style.dim("Hash ")} ${built.transactionHash}`);
511
+ print("");
512
+ print(style.dim("Re-run without --dry-run to sign and submit."));
513
+ }
514
+ function emitSendResult(side, target, result, json) {
515
+ const waited = "blockNumber" in result;
516
+ const payload = waited ? {
517
+ side,
518
+ target,
519
+ transactionHash: result.transactionHash,
520
+ blockNumber: result.blockNumber.toString(),
521
+ success: result.success,
522
+ gasUsed: result.gasUsed.toString()
523
+ } : {
524
+ side,
525
+ target,
526
+ transactionHash: result.transactionHash,
527
+ waited: false
528
+ };
529
+ if (json) {
530
+ printJson(payload);
531
+ return;
532
+ }
533
+ print("");
534
+ if (waited) {
535
+ if (result.success) {
536
+ log.success(`${side} included in block ${result.blockNumber.toString()}.`);
537
+ } else {
538
+ log.error(`${side} included but reverted on-chain.`);
539
+ }
540
+ print(` ${style.dim("Tx ")} ${result.transactionHash}`);
541
+ print(` ${style.dim("Block ")} ${result.blockNumber.toString()}`);
542
+ print(` ${style.dim("Gas ")} ${result.gasUsed.toString()}`);
543
+ } else {
544
+ log.success(`${side} submitted (fire-and-forget).`);
545
+ print(` ${style.dim("Tx ")} ${result.transactionHash}`);
546
+ }
547
+ }
548
+ export {
549
+ eoaCommand
550
+ };
551
+ //# sourceMappingURL=eoa-IQ72EIHR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/eoa/index.ts","../src/utils/eoa-client.ts"],"sourcesContent":["/**\n * `kash eoa …` — non-custodial direct-to-chain operations using a\n * vanilla EOA (no smart account, no bundler).\n *\n * Wraps `@kashdao/protocol-sdk`'s `createEoaClient`. Best for:\n * - Market makers with existing EIP-1559 signing infra (web3signer,\n * Fireblocks, AWS-KMS, etc.).\n * - Operators who don't want to provision a bundler.\n * - Lowest per-trade gas overhead.\n *\n * Required profile fields:\n * - `rpcUrl` — consumer-owned RPC endpoint\n * - `defaultChainId`— chain to run on\n * - `signerKeyRef` — `file:<path>` or `env:<NAME>` for the EOA key\n *\n * EOA mode does NOT use `smartAccount`, `bundlerUrl`, or\n * `bundlerProvider` — they're SA-mode-only fields.\n *\n * **Surface parity with `kash protocol`.** This namespace mirrors the\n * SA-mode read commands and the trade-execution commands. The\n * UserOp-specific lifecycle (`userop build/simulate/submit/wait/...`)\n * doesn't apply to EOA mode — instead, EOA mode signs serialized\n * EIP-1559 transactions directly. The CLI's `eoa trade {buy,sell,close,approve}`\n * commands run the same all-in-one flow.\n */\n\nimport { Command } from 'commander';\n\nimport { CliValidationError, toCliError } from '../../errors.js';\nimport { buildEoaClient } from '../../utils/eoa-client.js';\nimport { formatAddress, formatGwei, formatUsdcAtomic } from '../../utils/formatting.js';\nimport {\n parseOptionalPositiveFloat,\n parseOptionalPositiveInt,\n parsePositiveInt,\n readGlobals,\n} from '../../utils/global-options.js';\nimport { log, print, printJson, style } from '../../utils/output.js';\nimport {\n DEFAULT_SLIPPAGE_BPS,\n MAX_UINT256,\n type TradeOpSide,\n decimalToAtomicUsdc,\n decimalToAtomicWad,\n extractPartialHash,\n parseDeadlineSec,\n parseOutcomeIndex,\n parseSlippageBps,\n parseUppercaseSide,\n validateAddress,\n validateAddressOptional,\n} from '../../utils/trade-input.js';\n\n// ---------------------------------------------------------------------------\n// Reads: balance, market, quote, position, allowance, fees\n// ---------------------------------------------------------------------------\n\nconst balanceCommand = new Command('balance')\n .description(\n \"Read on-chain USDC + native gas balances for the EOA (defaults to signer's address).\"\n )\n .argument('[account]', \"address to read (default: signer's ownerAddress)\")\n .action(async (account: string | undefined, _opts, cmd: Command) => {\n const globals = readGlobals(cmd);\n const accountAddress = validateAddressOptional(account, 'account');\n try {\n const resolved = await buildEoaClient({ globals });\n const target = accountAddress ?? resolved.account;\n const [usdc, gas] = await Promise.all([\n resolved.client.account.usdcBalance(target),\n resolved.client.account.gasBalance(target),\n ]);\n\n const payload = {\n account: target,\n chainId: resolved.chainId,\n usdcAtomic: usdc.toString(),\n gasWei: gas.toString(),\n };\n if (globals.json) {\n printJson(payload);\n return;\n }\n print('');\n print(` ${style.dim('Account ')} ${formatAddress(target, 10, 8)}`);\n print(` ${style.dim('Chain ')} ${String(resolved.chainId)}`);\n print(` ${style.dim('USDC ')} ${formatUsdcAtomic(usdc.toString())}`);\n print(\n ` ${style.dim('Gas ')} ${formatGwei(gas)} gwei ${style.dim(`(${gas.toString()} wei)`)}`\n );\n } catch (cause) {\n throw toCliError(cause);\n }\n });\n\nconst marketCommand = new Command('market')\n .description('Read on-chain market state (reserves, supplies, weights, derived probabilities).')\n .argument('<address>', 'market contract address (0x-prefixed)')\n .action(async (address: string, _opts, cmd: Command) => {\n const globals = readGlobals(cmd);\n const marketAddress = validateAddress(address, 'address');\n try {\n const resolved = await buildEoaClient({ globals });\n const state = await resolved.client.markets.state(marketAddress);\n const payload = {\n marketAddress: state.marketAddress,\n chainId: resolved.chainId,\n status: state.status,\n readAt: state.readAt.toString(),\n reserveWad: state.reserveWad.toString(),\n outcomes: state.outcomes.map((o) => ({\n index: o.index,\n outstandingTokensWad: o.outstandingTokensWad.toString(),\n weightWad: o.weightWad.toString(),\n probability: o.probability,\n })),\n };\n if (globals.json) {\n printJson(payload);\n return;\n }\n print('');\n print(` ${style.dim('Market ')} ${formatAddress(state.marketAddress, 10, 8)}`);\n print(` ${style.dim('Status ')} ${state.status}`);\n print(` ${style.dim('Outcomes ')} ${String(state.outcomes.length)}`);\n print('');\n for (const outcome of state.outcomes) {\n const pct = (outcome.probability * 100).toFixed(2);\n print(` [${String(outcome.index)}] p=${pct}%`);\n }\n } catch (cause) {\n throw toCliError(cause);\n }\n });\n\ntype QuoteOptions = { side: string; outcome: string; amount: string };\n\nconst quoteCommand = new Command('quote')\n .description('On-chain price quote for buying or selling an outcome.')\n .argument('<address>', 'market contract address')\n .requiredOption('-s, --side <side>', 'buy | sell')\n .requiredOption('-o, --outcome <index>', 'outcome index (0-based)')\n .requiredOption('-a, --amount <decimal>', 'USDC for buy / outcome tokens for sell')\n .action(async (address: string, options: QuoteOptions, cmd: Command) => {\n const globals = readGlobals(cmd);\n const marketAddress = validateAddress(address, 'address');\n const side = parseUppercaseSide(options.side);\n const outcome = parseOutcomeIndex(options.outcome);\n const amount =\n side === 'BUY'\n ? decimalToAtomicUsdc(options.amount, 'amount')\n : decimalToAtomicWad(options.amount, 'amount');\n\n try {\n const resolved = await buildEoaClient({ globals });\n const quote = await resolved.client.markets.quote(marketAddress, {\n side,\n outcome,\n amount,\n });\n const payload = {\n side: quote.side,\n outcomeIndex: quote.outcomeIndex,\n amountIn: quote.amountIn.toString(),\n amountOut: quote.amountOut.toString(),\n reserveAfterWad: quote.reserveAfterWad.toString(),\n pricesAfterWad: quote.pricesAfterWad.map((p) => p.toString()),\n };\n if (globals.json) {\n printJson(payload);\n return;\n }\n print('');\n print(` ${style.dim('Side ')} ${quote.side}`);\n print(` ${style.dim('Outcome ')} ${String(quote.outcomeIndex)}`);\n print(` ${style.dim('In ')} ${quote.amountIn.toString()}`);\n print(` ${style.dim('Out ')} ${quote.amountOut.toString()}`);\n } catch (cause) {\n throw toCliError(cause);\n }\n });\n\nconst positionCommand = new Command('position')\n .description('Read on-chain outcome-token holdings (ERC-1155) for a market.')\n .argument('<market>', 'market contract address (0x-prefixed)')\n .argument('[account]', \"address whose holdings to read (default: signer's)\")\n .action(async (market: string, account: string | undefined, _opts, cmd: Command) => {\n const globals = readGlobals(cmd);\n const marketAddress = validateAddress(market, 'market');\n const accountAddress = validateAddressOptional(account, 'account');\n try {\n const resolved = await buildEoaClient({ globals });\n const target = accountAddress ?? resolved.account;\n const position = await resolved.client.account.position(target, marketAddress);\n const payload = {\n account: target,\n marketAddress: position.marketAddress,\n chainId: resolved.chainId,\n numOutcomes: position.numOutcomes,\n holdings: position.holdings.map((h) => ({\n outcomeIndex: h.outcomeIndex,\n balanceWad: h.balanceWad.toString(),\n })),\n };\n if (globals.json) {\n printJson(payload);\n return;\n }\n print('');\n print(` ${style.dim('Account ')} ${formatAddress(target, 10, 8)}`);\n print(` ${style.dim('Market ')} ${formatAddress(position.marketAddress, 10, 8)}`);\n print('');\n for (const h of position.holdings) {\n print(` [${String(h.outcomeIndex)}] balance=${h.balanceWad.toString()} (WAD)`);\n }\n } catch (cause) {\n throw toCliError(cause);\n }\n });\n\nconst allowanceCommand = new Command('allowance')\n .description('Read the on-chain USDC allowance from `account` to `spender`.')\n .argument('<spender>', 'spender contract address')\n .argument('[account]', \"owner address (default: signer's)\")\n .action(async (spender: string, account: string | undefined, _opts, cmd: Command) => {\n const globals = readGlobals(cmd);\n const spenderAddress = validateAddress(spender, 'spender');\n const accountAddress = validateAddressOptional(account, 'account');\n try {\n const resolved = await buildEoaClient({ globals });\n const owner = accountAddress ?? resolved.account;\n const allowance = await resolved.client.account.usdcAllowance(owner, spenderAddress);\n const payload = {\n owner,\n spender,\n chainId: resolved.chainId,\n allowanceAtomic: allowance.toString(),\n };\n if (globals.json) {\n printJson(payload);\n return;\n }\n print('');\n print(` ${style.dim('Owner ')} ${formatAddress(owner, 10, 8)}`);\n print(` ${style.dim('Spender ')} ${formatAddress(spender, 10, 8)}`);\n print(` ${style.dim('Allowance')} ${formatUsdcAtomic(allowance.toString())}`);\n } catch (cause) {\n throw toCliError(cause);\n }\n });\n\nconst feesCommand = new Command('fees')\n .description('EIP-1559 fee estimate for the configured chain.')\n .option('--blocks <n>', 'number of recent blocks to sample (default 4)')\n .option('--percentile <n>', 'priority-fee percentile per block (1-99, default 50)')\n .option('--base-multiplier <n>', 'multiplier on predicted next-block base fee (default 2.0)')\n .option('--priority-floor-gwei <n>', 'floor for maxPriorityFeePerGas in gwei (default 1)')\n .action(\n async (\n options: {\n blocks?: string;\n percentile?: string;\n baseMultiplier?: string;\n priorityFloorGwei?: string;\n },\n cmd: Command\n ) => {\n const globals = readGlobals(cmd);\n const blocks = parseOptionalPositiveInt(options.blocks, 'blocks');\n const percentile = parseOptionalPositiveInt(options.percentile, 'percentile');\n if (percentile !== undefined && (percentile < 1 || percentile > 99)) {\n throw new CliValidationError('--percentile must be between 1 and 99.');\n }\n const baseMultiplier = parseOptionalPositiveFloat(options.baseMultiplier, 'base-multiplier');\n const priorityFloorGwei = parseOptionalPositiveInt(\n options.priorityFloorGwei,\n 'priority-floor-gwei'\n );\n\n try {\n const resolved = await buildEoaClient({ globals });\n const estimate = await resolved.client.estimateFees({\n ...(blocks === undefined ? {} : { blockCount: blocks }),\n ...(percentile === undefined ? {} : { rewardPercentile: percentile }),\n ...(baseMultiplier === undefined ? {} : { baseMultiplier }),\n ...(priorityFloorGwei === undefined\n ? {}\n : { priorityFeeFloorWei: BigInt(priorityFloorGwei) * 10n ** 9n }),\n });\n\n const payload = {\n chainId: resolved.chainId,\n maxFeePerGas: estimate.maxFeePerGas.toString(),\n maxPriorityFeePerGas: estimate.maxPriorityFeePerGas.toString(),\n };\n if (globals.json) {\n printJson(payload);\n return;\n }\n print('');\n print(\n ` ${style.dim('maxFee ')} ${formatGwei(estimate.maxFeePerGas)} gwei (${estimate.maxFeePerGas.toString()} wei)`\n );\n print(\n ` ${style.dim('maxPrio ')} ${formatGwei(estimate.maxPriorityFeePerGas)} gwei (${estimate.maxPriorityFeePerGas.toString()} wei)`\n );\n } catch (cause) {\n throw toCliError(cause);\n }\n }\n );\n\n// ---------------------------------------------------------------------------\n// Trade execution: buy, sell, close, approve\n// ---------------------------------------------------------------------------\n\ntype SharedTradeOptions = {\n outcome?: string;\n slippageBps?: string;\n deadlineSec?: string;\n dryRun?: boolean;\n // Commander stores `--no-X` as `{ x: false }`. Default is undefined\n // (meaning the user did not pass the negative flag); explicit `false`\n // means they did. Same idiom as `--no-overwrite` in `config import`.\n simulate?: boolean;\n wait?: boolean;\n waitTimeoutMs?: string;\n};\n\ntype Side = TradeOpSide;\n\nconst tradeBuyCommand = new Command('buy')\n .description('One-shot BUY (EIP-1559 tx, signed locally and submitted to chain).')\n .argument('<market>', 'market contract address')\n .requiredOption('-o, --outcome <index>', 'outcome index (0-based)')\n .requiredOption('-a, --amount <usdc>', 'USDC to spend (decimal)')\n .option('--slippage-bps <n>', 'slippage tolerance in bps (default 50)')\n .option('--deadline-sec <n>', 'unix-seconds deadline (default now + 5min)')\n .option('--dry-run', 'prepare + simulate but DO NOT sign or submit')\n .option('--no-simulate', 'skip eth_call preflight')\n .option('--no-wait', 'fire-and-forget: return tx hash without waiting for inclusion')\n .option('--wait-timeout-ms <n>', 'cap on the receipt wait (default 60000)')\n .action(\n async (market: string, options: SharedTradeOptions & { amount: string }, cmd: Command) => {\n await runTrade('buy', market, options, cmd);\n }\n );\n\nconst tradeSellCommand = new Command('sell')\n .description('One-shot SELL.')\n .argument('<market>', 'market contract address')\n .requiredOption('-o, --outcome <index>', 'outcome index (0-based)')\n .requiredOption('-t, --tokens <amount>', 'outcome tokens to sell (WAD decimal)')\n .option('--slippage-bps <n>', 'slippage tolerance in bps (default 50)')\n .option('--deadline-sec <n>', 'unix-seconds deadline (default now + 5min)')\n .option('--dry-run', 'prepare + simulate but DO NOT sign or submit')\n .option('--no-simulate', 'skip eth_call preflight')\n .option('--no-wait', 'fire-and-forget')\n .option('--wait-timeout-ms <n>', 'cap on the receipt wait (default 60000)')\n .action(\n async (market: string, options: SharedTradeOptions & { tokens: string }, cmd: Command) => {\n await runTrade('sell', market, options, cmd);\n }\n );\n\nconst tradeCloseCommand = new Command('close')\n .description('Sell the entire EOA balance for an outcome.')\n .argument('<market>', 'market contract address')\n .requiredOption('-o, --outcome <index>', 'outcome index (0-based)')\n .option('--slippage-bps <n>', 'slippage tolerance in bps (default 50)')\n .option('--deadline-sec <n>', 'unix-seconds deadline (default now + 5min)')\n .option('--dry-run', 'prepare + simulate but DO NOT sign or submit')\n .option('--no-simulate', 'skip eth_call preflight')\n .option('--no-wait', 'fire-and-forget')\n .option('--wait-timeout-ms <n>', 'cap on the receipt wait (default 60000)')\n .action(async (market: string, options: SharedTradeOptions, cmd: Command) => {\n await runTrade('close', market, options, cmd);\n });\n\nconst tradeApproveCommand = new Command('approve')\n .description('USDC approval — required once before the first BUY.')\n .argument('<spender>', 'spender contract address (typically a Market)')\n .option('-a, --amount <usdc>', 'atomic-USDC amount (default unlimited)')\n .option('--dry-run', 'prepare + simulate but DO NOT sign or submit')\n .option('--no-simulate', 'skip eth_call preflight')\n .option('--no-wait', 'fire-and-forget')\n .option('--wait-timeout-ms <n>', 'cap on the receipt wait (default 60000)')\n .action(\n async (\n spender: string,\n options: {\n amount?: string;\n dryRun?: boolean;\n simulate?: boolean;\n wait?: boolean;\n waitTimeoutMs?: string;\n },\n cmd: Command\n ) => {\n const globals = readGlobals(cmd);\n const spenderAddress = validateAddress(spender, 'spender');\n const amount = options.amount ? decimalToAtomicUsdc(options.amount, 'amount') : MAX_UINT256;\n const waitTimeoutMs = options.waitTimeoutMs\n ? parsePositiveInt(options.waitTimeoutMs, 'wait-timeout-ms')\n : undefined;\n\n try {\n const resolved = await buildEoaClient({ globals });\n const params = {\n account: resolved.account,\n spender: spenderAddress,\n amount,\n };\n\n if (options.dryRun === true) {\n const built = await resolved.client.trades.prepareApprove(params, {\n simulate: options.simulate !== false,\n });\n emitDryRun('approve', spender, built, globals.json);\n return;\n }\n\n const sendOptions = {\n simulate: options.simulate !== false,\n wait: options.wait !== false,\n ...(waitTimeoutMs === undefined ? {} : { waitTimeoutMs }),\n };\n let result;\n try {\n result = await resolved.client.trades.send.approve(params, sendOptions);\n } catch (cause) {\n // Approves cost gas — same partial-completion concern as\n // buy/sell/close. The EOA SDK's `sendApproveTransaction`\n // shares `dispatch` with the trade calls, so it throws the\n // identical KashChainError(WAIT_RECEIPT_FAILED) shape on\n // post-submit wait timeout. Surface the hash so the\n // operator can verify inclusion before paying gas for a\n // duplicate approve.\n const partialHash = extractPartialTransactionHash(cause);\n if (partialHash !== undefined) {\n if (globals.json) {\n printJson({ transactionHash: partialHash, waited: false, partial: true });\n } else {\n log.warn(\n `Submit succeeded but wait timed out. The approve tx is on-chain — check inclusion via your block explorer for: ${partialHash}`\n );\n }\n }\n throw cause;\n }\n emitSendResult('approve', spender, result, globals.json);\n } catch (cause) {\n throw toCliError(cause);\n }\n }\n );\n\nconst tradeCommand = new Command('trade')\n .description('Direct-mode trade execution (vanilla EIP-1559 tx, signed locally).')\n .addHelpText(\n 'after',\n `\nWait controls — surface parity with \\`kash protocol trade\\`:\n --wait-timeout-ms <n> Cap on the receipt wait (supported).\n --wait-interval-ms NOT exposed in EOA mode. viem's\n \\`waitForTransactionReceipt\\` controls its\n own polling cadence based on chain block\n time; the EOA SDK does not pass through a\n custom interval. Use SA mode\n (\\`kash protocol trade\\`) if you need\n fine-grained interval control.\n`\n )\n .addCommand(tradeBuyCommand)\n .addCommand(tradeSellCommand)\n .addCommand(tradeCloseCommand)\n .addCommand(tradeApproveCommand);\n\n// ---------------------------------------------------------------------------\n// Top-level eoa namespace\n// ---------------------------------------------------------------------------\n\nexport const eoaCommand = new Command('eoa')\n .description(\n 'Self-orchestrated direct-to-chain operations using a vanilla EOA (no smart account). Like every Kash entry point, this path is non-custodial.'\n )\n .addCommand(balanceCommand)\n .addCommand(marketCommand)\n .addCommand(quoteCommand)\n .addCommand(positionCommand)\n .addCommand(allowanceCommand)\n .addCommand(feesCommand)\n .addCommand(tradeCommand);\n\n// ---------------------------------------------------------------------------\n// Trade runner (shared across buy/sell/close)\n// ---------------------------------------------------------------------------\n\nasync function runTrade(\n side: Side,\n market: string,\n options: SharedTradeOptions & { amount?: string; tokens?: string },\n cmd: Command\n): Promise<void> {\n const globals = readGlobals(cmd);\n const marketAddress = validateAddress(market, 'market');\n const outcome = parseOutcomeIndex(options.outcome);\n const slippageBps = options.slippageBps\n ? parseSlippageBps(options.slippageBps)\n : DEFAULT_SLIPPAGE_BPS;\n const deadline = options.deadlineSec ? parseDeadlineSec(options.deadlineSec) : undefined;\n const waitTimeoutMs = options.waitTimeoutMs\n ? parsePositiveInt(options.waitTimeoutMs, 'wait-timeout-ms')\n : undefined;\n\n let amountUsdc: bigint | undefined;\n let amountTokens: bigint | undefined;\n if (side === 'buy') {\n amountUsdc = decimalToAtomicUsdc(options.amount!, 'amount');\n } else if (side === 'sell') {\n amountTokens = decimalToAtomicWad(options.tokens!, 'tokens');\n }\n\n try {\n const resolved = await buildEoaClient({ globals });\n // **EOA / SA param-shape note.** The shared `BuildBuyParams` /\n // `BuildSellParams` shapes the SDK exposes still use a\n // `smartAccount: Hex` field name in EOA mode for back-compat with\n // SA-mode call sites. The SDK accepts the EOA address here as the\n // signing-account hint — see protocol-sdk's `eoa/trades/build.ts`.\n // The pinning-test in `tests/component/eoa.test.ts` asserts the\n // SDK still respects this aliasing so SDK upgrades that tighten\n // the field name surface as a test failure instead of a silent\n // mis-trade.\n const baseParams = {\n account: resolved.account,\n smartAccount: resolved.account,\n outcome,\n maxSlippageBps: slippageBps,\n ...(deadline === undefined ? {} : { deadline }),\n };\n const opts = { simulate: options.simulate !== false };\n\n if (options.dryRun === true) {\n let built;\n if (side === 'buy') {\n built = await resolved.client.trades.prepareBuy(\n marketAddress,\n { ...baseParams, amountUsdc: amountUsdc! },\n opts\n );\n } else if (side === 'sell') {\n built = await resolved.client.trades.prepareSell(\n marketAddress,\n { ...baseParams, amountTokens: amountTokens! },\n opts\n );\n } else {\n built = await resolved.client.trades.prepareClosePosition(marketAddress, baseParams, opts);\n }\n emitDryRun(side, market, built, globals.json);\n return;\n }\n\n const sendOptions = {\n simulate: options.simulate !== false,\n wait: options.wait !== false,\n ...(waitTimeoutMs === undefined ? {} : { waitTimeoutMs }),\n };\n\n let result;\n try {\n if (side === 'buy') {\n result = await resolved.client.trades.send.buy(\n marketAddress,\n { ...baseParams, amountUsdc: amountUsdc! },\n sendOptions\n );\n } else if (side === 'sell') {\n result = await resolved.client.trades.send.sell(\n marketAddress,\n { ...baseParams, amountTokens: amountTokens! },\n sendOptions\n );\n } else {\n result = await resolved.client.trades.send.closePosition(\n marketAddress,\n baseParams,\n sendOptions\n );\n }\n } catch (cause) {\n // Partial-completion guard symmetric to the SA-mode path. The\n // EOA SDK throws KashChainError with `code: 'WAIT_RECEIPT_FAILED'`\n // and `context.transactionHash` when submit succeeded but the\n // wait phase timed out (see\n // `protocol-sdk/src/eoa/trades/send.ts:273-281`). Surface that\n // hash so the operator doesn't pay gas and lose the inclusion\n // pointer. The discriminator is narrow on purpose so unrelated\n // KashChainErrors (chain RPC failures, contract reverts) don't\n // get mis-reported as partial completions.\n const partialHash = extractPartialTransactionHash(cause);\n if (partialHash !== undefined) {\n if (globals.json) {\n printJson({ transactionHash: partialHash, waited: false, partial: true });\n } else {\n log.warn(\n `Submit succeeded but wait timed out. The tx is on-chain — check inclusion via your block explorer for: ${partialHash}`\n );\n }\n }\n throw cause;\n }\n emitSendResult(side, market, result, globals.json);\n } catch (cause) {\n throw toCliError(cause);\n }\n}\n\n/**\n * EOA-mode wrapper around the canonical `extractPartialHash` factory\n * (`utils/trade-input.ts`). Pinned to the wait-receipt-failed code so\n * pre-submit `KashChainError` variants (`CHAIN_RPC_FAILED`, etc.)\n * don't masquerade as partial completions.\n *\n * SDK throw site: `protocol-sdk/src/eoa/trades/send.ts:273-281`.\n */\nfunction extractPartialTransactionHash(cause: unknown): `0x${string}` | undefined {\n return extractPartialHash(cause, {\n code: 'WAIT_RECEIPT_FAILED',\n contextKey: 'transactionHash',\n });\n}\n\n// ---------------------------------------------------------------------------\n// Output emitters\n// ---------------------------------------------------------------------------\n\ntype BuiltTxLike = {\n transaction: Record<string, unknown>;\n transactionHash: `0x${string}`;\n};\n\nfunction emitDryRun(\n side: Side | 'approve',\n target: string,\n built: BuiltTxLike,\n json: boolean\n): void {\n if (json) {\n // `printJson`'s jsonReplacer is the single source of truth for\n // bigint-in-JSON: it coerces every bigint field on `transaction`\n // to a decimal string. No pre-conversion needed here.\n printJson({\n side,\n target,\n transaction: built.transaction,\n transactionHash: built.transactionHash,\n dryRun: true,\n });\n return;\n }\n print('');\n print(` ${style.bold('Dry run')} — transaction prepared but NOT signed/submitted.`);\n print(` ${style.dim('Side ')} ${side}`);\n print(` ${style.dim('Target')} ${formatAddress(target, 10, 8)}`);\n print(` ${style.dim('Hash ')} ${built.transactionHash}`);\n print('');\n print(style.dim('Re-run without --dry-run to sign and submit.'));\n}\n\ntype SendResultLike =\n | { transactionHash: `0x${string}` }\n | {\n transactionHash: `0x${string}`;\n blockNumber: bigint;\n success: boolean;\n gasUsed: bigint;\n };\n\nfunction emitSendResult(\n side: Side | 'approve',\n target: string,\n result: SendResultLike,\n json: boolean\n): void {\n const waited = 'blockNumber' in result;\n const payload = waited\n ? {\n side,\n target,\n transactionHash: result.transactionHash,\n blockNumber: result.blockNumber.toString(),\n success: result.success,\n gasUsed: result.gasUsed.toString(),\n }\n : {\n side,\n target,\n transactionHash: result.transactionHash,\n waited: false,\n };\n\n if (json) {\n printJson(payload);\n return;\n }\n\n print('');\n if (waited) {\n if (result.success) {\n log.success(`${side} included in block ${result.blockNumber.toString()}.`);\n } else {\n log.error(`${side} included but reverted on-chain.`);\n }\n print(` ${style.dim('Tx ')} ${result.transactionHash}`);\n print(` ${style.dim('Block ')} ${result.blockNumber.toString()}`);\n print(` ${style.dim('Gas ')} ${result.gasUsed.toString()}`);\n } else {\n log.success(`${side} submitted (fire-and-forget).`);\n print(` ${style.dim('Tx ')} ${result.transactionHash}`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// EOA-mode-only helpers (the shared trade-input parsers live in\n// `utils/trade-input.ts`).\n// ---------------------------------------------------------------------------\n\n// `formatGwei` lives in `utils/formatting.ts` — shared with\n// protocol/fees and balance renderers.\n// `parseOptionalPositiveInt` / `parseOptionalPositiveFloat` live in\n// `utils/global-options.ts` — single source for positive-bound parsers\n// across every CLI command.\n","/**\n * Build a `@kashdao/protocol-sdk` `EoaClient` from the active\n * profile's direct-mode config.\n *\n * EOA mode is the parallel non-custodial path to smart-account mode\n * (`buildDirectClient` in `direct-client.ts`). It signs vanilla\n * EIP-1559 transactions instead of UserOps; the signer's address IS\n * the trading account. Required config:\n *\n * - `rpcUrl` — same field as SA mode\n * - `signerKeyRef` — same field as SA mode (file: or env:)\n * - `defaultChainId` — same field as SA mode\n *\n * EOA mode does NOT need:\n * - `smartAccount` (the EOA address is derived from the signer)\n * - `bundlerUrl` / `bundlerProvider` (no bundler involvement)\n *\n * **Lazy-loaded.** Same cold-start firewall as `direct-client.ts` —\n * the dynamic `import('@kashdao/protocol-sdk')` keeps viem out of the\n * non-EOA paths.\n */\n\nimport { CliError, EXIT_CODES } from '../errors.js';\n\nimport { readConfig, type CliConfig } from './config-store.js';\nimport { resolveCliCustomChain } from './custom-chain.js';\nimport { loadRawPrivateKey } from './signer-key.js';\n\nimport type { GlobalOptions } from './global-options.js';\nimport type { CustomChain, EoaClient, EoaSignerAdapter } from '@kashdao/protocol-sdk';\n\n/**\n * Build a configured `EoaClient`. `requireSigner` is always `true`\n * here — there's no read-only EOA mode (the signer address is the\n * trading account, and reads need the address). Reads against an\n * arbitrary address are still possible by passing the address as a\n * positional argument; the signer just provides the default.\n */\nexport async function buildEoaClient(opts: { readonly globals?: GlobalOptions }): Promise<{\n readonly client: EoaClient;\n readonly chainId: number;\n readonly account: `0x${string}`;\n}> {\n const globals = opts.globals;\n const config = await readConfig({\n ...(globals?.profile === undefined ? {} : { profile: globals.profile }),\n ...(globals?.configPath === undefined ? {} : { configPath: globals.configPath }),\n });\n\n const rpc = globals?.baseUrl ?? config.rpcUrl;\n if (!rpc) {\n throw missingEoaConfig('rpcUrl', '--rpc-url or `kash config set rpcUrl <url>`');\n }\n if (!config.signerKeyRef) {\n throw missingEoaConfig(\n 'signerKeyRef',\n '`kash config set signerKeyRef file:<path>` or `env:<NAME>` (CLI never persists raw keys)'\n );\n }\n\n const { createEoaClient } = await import('@kashdao/protocol-sdk');\n const signer = await loadEoaSigner(config.signerKeyRef);\n\n // If the profile has `customChain` configured, build the SDK\n // CustomChain (viem chain + addresses) so we work against chains\n // outside the static registry — local Anvil, forks, sidechains.\n // EOA mode ignores `customChain.smartAccount`.\n const customChain = await maybeBuildCustomChain(config, rpc);\n\n const client = createEoaClient({\n chainId: config.defaultChainId,\n rpc,\n signer,\n ...(customChain === undefined ? {} : { customChain }),\n });\n\n return {\n client,\n chainId: config.defaultChainId,\n account: signer.ownerAddress,\n };\n}\n\n/**\n * Load an EOA signer from `signerKeyRef`. Mirrors the SA-mode\n * `loadSigner` in `direct-client.ts` but wraps via\n * `viemAccountEoaSigner` for vanilla-tx signing instead of\n * `viemAccountSigner` for UserOp hash signing.\n */\nasync function loadEoaSigner(ref: string): Promise<EoaSignerAdapter> {\n const rawKey = await loadRawPrivateKey(ref);\n // Lazy-load viem + the EOA signer adapter together (matches the\n // SA-mode boundary in `direct-client.ts`). Different adapter, same\n // dynamic-import gate.\n const [{ privateKeyToAccount }, { viemAccountEoaSigner }] = await Promise.all([\n import('viem/accounts'),\n import('@kashdao/protocol-sdk'),\n ]);\n return viemAccountEoaSigner(privateKeyToAccount(rawKey));\n}\n\n/**\n * Build an SDK `CustomChain` from the profile's `customChain` config,\n * if any. The CLI never asks the user to hand-construct a viem Chain\n * — we synthesise one from `defaultChainId + rpcUrl + customChain.name`,\n * which is exactly what the local-anvil quickstart in\n * `packages/protocol-sdk/examples/local-anvil/` does inline.\n */\nasync function maybeBuildCustomChain(\n config: CliConfig,\n rpc: string\n): Promise<CustomChain | undefined> {\n if (config.customChain === undefined) return undefined;\n if (config.defaultChainId === undefined) {\n throw missingEoaConfig(\n 'defaultChainId',\n '`kash config set defaultChainId <id>` (required when customChain is set so the CLI can construct the viem chain)'\n );\n }\n return resolveCliCustomChain({\n customChain: config.customChain,\n chainId: config.defaultChainId,\n rpc,\n });\n}\n\nfunction missingEoaConfig(field: string, hint: string): CliError {\n return new CliError(`EOA-mode config missing: ${field}.`, {\n code: 'DIRECT_CONFIG_MISSING',\n exitCode: EXIT_CODES.GENERIC,\n suggestion: `Set ${field} via ${hint}.`,\n actions: [\n {\n type: 'check_input',\n field,\n description: hint,\n },\n ],\n });\n}\n"],"mappings":"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","names":[]}