@gaberoo/kalshitools 1.0.1 → 1.0.3

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 (47) hide show
  1. package/README.md +91 -27
  2. package/dist/commands/config/init.js +4 -4
  3. package/dist/commands/config/show.js +5 -5
  4. package/dist/commands/markets/list.d.ts +5 -1
  5. package/dist/commands/markets/list.js +28 -8
  6. package/dist/commands/markets/orderbook.d.ts +13 -0
  7. package/dist/commands/markets/orderbook.js +83 -0
  8. package/dist/commands/markets/show.d.ts +3 -3
  9. package/dist/commands/markets/show.js +7 -7
  10. package/dist/commands/orders/cancel.d.ts +3 -3
  11. package/dist/commands/orders/cancel.js +7 -7
  12. package/dist/commands/orders/create.d.ts +5 -5
  13. package/dist/commands/orders/create.js +33 -33
  14. package/dist/commands/orders/list.d.ts +1 -1
  15. package/dist/commands/orders/list.js +9 -9
  16. package/dist/commands/portfolio/balance.js +11 -6
  17. package/dist/commands/portfolio/fills.d.ts +1 -1
  18. package/dist/commands/portfolio/fills.js +7 -7
  19. package/dist/commands/portfolio/positions.d.ts +1 -0
  20. package/dist/commands/portfolio/positions.js +11 -2
  21. package/dist/lib/base-command.d.ts +2 -2
  22. package/dist/lib/base-command.js +8 -8
  23. package/dist/lib/config/manager.d.ts +25 -25
  24. package/dist/lib/config/manager.js +51 -51
  25. package/dist/lib/config/schema.d.ts +11 -11
  26. package/dist/lib/config/schema.js +6 -6
  27. package/dist/lib/errors/base.d.ts +10 -10
  28. package/dist/lib/errors/base.js +7 -7
  29. package/dist/lib/kalshi/auth.d.ts +4 -4
  30. package/dist/lib/kalshi/auth.js +24 -24
  31. package/dist/lib/kalshi/client.d.ts +35 -35
  32. package/dist/lib/kalshi/client.js +101 -86
  33. package/dist/lib/kalshi/index.d.ts +1 -1
  34. package/dist/lib/kalshi/index.js +1 -1
  35. package/dist/lib/kalshi/types.d.ts +54 -54
  36. package/dist/lib/logger.js +3 -3
  37. package/dist/lib/output/formatter.d.ts +20 -20
  38. package/dist/lib/output/formatter.js +55 -55
  39. package/dist/lib/retry.d.ts +2 -2
  40. package/dist/lib/retry.js +8 -10
  41. package/dist/lib/sanitize.js +9 -9
  42. package/dist/lib/shutdown.d.ts +4 -4
  43. package/dist/lib/shutdown.js +7 -7
  44. package/dist/lib/validation.d.ts +5 -5
  45. package/dist/lib/validation.js +14 -20
  46. package/oclif.manifest.json +138 -47
  47. package/package.json +1 -1
@@ -16,45 +16,45 @@ export default class OrdersCreate extends BaseCommand {
16
16
  ];
17
17
  static flags = {
18
18
  ...BaseCommand.baseFlags,
19
- ticker: Flags.string({
20
- char: 't',
21
- description: 'Market ticker symbol',
22
- required: true,
23
- }),
24
19
  action: Flags.string({
25
20
  char: 'a',
26
21
  description: 'Order action (buy or sell)',
27
22
  options: ['buy', 'sell'],
28
23
  required: true,
29
24
  }),
25
+ 'dry-run': Flags.boolean({
26
+ default: false,
27
+ description: 'Simulate the order without actually placing it',
28
+ }),
29
+ price: Flags.string({
30
+ char: 'p',
31
+ description: 'Limit price (required for limit orders, 0.01-0.99)',
32
+ }),
33
+ quantity: Flags.integer({
34
+ char: 'q',
35
+ description: 'Number of contracts',
36
+ required: true,
37
+ }),
30
38
  side: Flags.string({
31
39
  char: 's',
32
40
  description: 'Contract side (yes or no)',
33
41
  options: ['yes', 'no'],
34
42
  required: true,
35
43
  }),
36
- quantity: Flags.integer({
37
- char: 'q',
38
- description: 'Number of contracts',
44
+ ticker: Flags.string({
45
+ char: 't',
46
+ description: 'Market ticker symbol',
39
47
  required: true,
40
48
  }),
41
49
  type: Flags.string({
50
+ default: 'market',
42
51
  description: 'Order type (market or limit)',
43
52
  options: ['market', 'limit'],
44
- default: 'market',
45
- }),
46
- price: Flags.string({
47
- char: 'p',
48
- description: 'Limit price (required for limit orders, 0.01-0.99)',
49
53
  }),
50
54
  yes: Flags.boolean({
51
55
  char: 'y',
52
- description: 'Skip confirmation prompt',
53
- default: false,
54
- }),
55
- 'dry-run': Flags.boolean({
56
- description: 'Simulate the order without actually placing it',
57
56
  default: false,
57
+ description: 'Skip confirmation prompt',
58
58
  }),
59
59
  };
60
60
  async run() {
@@ -84,10 +84,10 @@ export default class OrdersCreate extends BaseCommand {
84
84
  const costEstimate = estimateOrderCost(side, action, flags.quantity, price);
85
85
  // Build order request
86
86
  const orderRequest = {
87
- ticker: flags.ticker,
88
- side,
89
87
  action,
90
88
  count: flags.quantity,
89
+ side,
90
+ ticker: flags.ticker,
91
91
  type: orderType,
92
92
  };
93
93
  if (orderType === 'limit' && price) {
@@ -132,16 +132,16 @@ export default class OrdersCreate extends BaseCommand {
132
132
  if (flags['dry-run']) {
133
133
  if (this.formatter.isJSONMode()) {
134
134
  this.formatter.success({
135
+ costEstimate,
135
136
  dryRun: true,
136
137
  order: orderRequest,
137
- costEstimate,
138
138
  });
139
139
  }
140
140
  else {
141
141
  this.log(chalk.yellow('DRY RUN - Order not placed'));
142
142
  this.log(chalk.gray('Order would be submitted with the parameters above'));
143
143
  }
144
- logger.info({ orderRequest, dryRun: true }, 'Dry run order');
144
+ logger.info({ dryRun: true, orderRequest }, 'Dry run order');
145
145
  return;
146
146
  }
147
147
  // Confirmation prompt (unless --yes flag or JSON mode)
@@ -187,17 +187,6 @@ export default class OrdersCreate extends BaseCommand {
187
187
  throw error;
188
188
  }
189
189
  }
190
- formatStatus(status) {
191
- const colors = {
192
- executed: chalk.green,
193
- pending: chalk.yellow,
194
- resting: chalk.cyan,
195
- canceled: chalk.gray,
196
- expired: chalk.red,
197
- };
198
- const colorFn = colors[status] || chalk.white;
199
- return colorFn(status);
200
- }
201
190
  async confirm(message) {
202
191
  const readline = await import('node:readline/promises');
203
192
  const rl = readline.createInterface({
@@ -208,4 +197,15 @@ export default class OrdersCreate extends BaseCommand {
208
197
  rl.close();
209
198
  return answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes';
210
199
  }
200
+ formatStatus(status) {
201
+ const colors = {
202
+ canceled: chalk.gray,
203
+ executed: chalk.green,
204
+ expired: chalk.red,
205
+ pending: chalk.yellow,
206
+ resting: chalk.cyan,
207
+ };
208
+ const colorFn = colors[status] || chalk.white;
209
+ return colorFn(status);
210
+ }
211
211
  }
@@ -3,9 +3,9 @@ export default class OrdersList extends BaseCommand {
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  static flags: {
6
+ limit: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
6
7
  status: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
8
  ticker: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
- limit: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
9
9
  json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
10
  };
11
11
  run(): Promise<void>;
@@ -13,6 +13,10 @@ export default class OrdersList extends BaseCommand {
13
13
  ];
14
14
  static flags = {
15
15
  ...BaseCommand.baseFlags,
16
+ limit: Flags.integer({
17
+ default: 50,
18
+ description: 'Maximum number of orders to return',
19
+ }),
16
20
  status: Flags.string({
17
21
  description: 'Filter by order status',
18
22
  options: ['pending', 'resting', 'canceled', 'executed', 'expired'],
@@ -20,10 +24,6 @@ export default class OrdersList extends BaseCommand {
20
24
  ticker: Flags.string({
21
25
  description: 'Filter by ticker',
22
26
  }),
23
- limit: Flags.integer({
24
- description: 'Maximum number of orders to return',
25
- default: 50,
26
- }),
27
27
  };
28
28
  async run() {
29
29
  const { flags } = await this.parse(OrdersList);
@@ -32,13 +32,13 @@ export default class OrdersList extends BaseCommand {
32
32
  const client = createClientFromConfig();
33
33
  // Fetch orders
34
34
  const result = await client.getOrders({
35
+ limit: flags.limit,
35
36
  status: flags.status,
36
37
  ticker: flags.ticker,
37
- limit: flags.limit,
38
38
  });
39
- const orders = result.orders;
39
+ const { orders } = result;
40
40
  if (this.formatter.isJSONMode()) {
41
- this.formatter.success({ orders, cursor: result.cursor });
41
+ this.formatter.success({ cursor: result.cursor, orders });
42
42
  }
43
43
  else {
44
44
  if (orders.length === 0) {
@@ -80,11 +80,11 @@ export default class OrdersList extends BaseCommand {
80
80
  }
81
81
  formatStatus(status) {
82
82
  const colors = {
83
+ canceled: chalk.gray,
83
84
  executed: chalk.green,
85
+ expired: chalk.red,
84
86
  pending: chalk.yellow,
85
87
  resting: chalk.cyan,
86
- canceled: chalk.gray,
87
- expired: chalk.red,
88
88
  };
89
89
  const colorFn = colors[status] || chalk.white;
90
90
  return colorFn(status);
@@ -15,18 +15,23 @@ export default class PortfolioBalance extends BaseCommand {
15
15
  const client = createClientFromConfig();
16
16
  // Fetch balance
17
17
  const balance = await client.getBalance();
18
+ // Convert cents to dollars
19
+ const balanceDollars = balance.balance / 100;
20
+ const portfolioValueDollars = balance.portfolio_value / 100;
18
21
  if (this.formatter.isJSONMode()) {
19
- this.formatter.success(balance);
22
+ // Return in dollars for readability
23
+ this.formatter.success({
24
+ balance: balanceDollars,
25
+ portfolio_value: portfolioValueDollars,
26
+ });
20
27
  }
21
28
  else {
22
29
  this.log(chalk.cyan.bold('Account Balance'));
23
30
  this.log();
24
- this.log(`${chalk.cyan('Balance:')} ${chalk.green('$' + balance.balance.toFixed(2))}`);
25
- this.log(`${chalk.cyan('Payout:')} ${chalk.yellow('$' + balance.payout.toFixed(2))}`);
26
- this.log();
27
- this.log(chalk.gray(`Total: $${(balance.balance + balance.payout).toFixed(2)}`));
31
+ this.log(`${chalk.cyan('Available:')} ${chalk.green('$' + balanceDollars.toFixed(2))}`);
32
+ this.log(`${chalk.cyan('Portfolio Value:')} ${chalk.yellow('$' + portfolioValueDollars.toFixed(2))}`);
28
33
  }
29
- logger.info({ balance: balance.balance, payout: balance.payout }, 'Balance fetched successfully');
34
+ logger.info({ balance: balanceDollars, portfolio_value: portfolioValueDollars }, 'Balance fetched successfully');
30
35
  }
31
36
  catch (error) {
32
37
  // Error will be handled by BaseCommand.catch()
@@ -3,8 +3,8 @@ export default class PortfolioFills extends BaseCommand {
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  static flags: {
6
- ticker: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
6
  limit: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
7
+ ticker: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
8
  json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
9
  };
10
10
  run(): Promise<void>;
@@ -13,12 +13,12 @@ export default class PortfolioFills extends BaseCommand {
13
13
  ];
14
14
  static flags = {
15
15
  ...BaseCommand.baseFlags,
16
- ticker: Flags.string({
17
- description: 'Filter by ticker',
18
- }),
19
16
  limit: Flags.integer({
20
- description: 'Maximum number of fills to return',
21
17
  default: 50,
18
+ description: 'Maximum number of fills to return',
19
+ }),
20
+ ticker: Flags.string({
21
+ description: 'Filter by ticker',
22
22
  }),
23
23
  };
24
24
  async run() {
@@ -28,12 +28,12 @@ export default class PortfolioFills extends BaseCommand {
28
28
  const client = createClientFromConfig();
29
29
  // Fetch fills
30
30
  const result = await client.getFills({
31
- ticker: flags.ticker,
32
31
  limit: flags.limit,
32
+ ticker: flags.ticker,
33
33
  });
34
- const fills = result.fills;
34
+ const { fills } = result;
35
35
  if (this.formatter.isJSONMode()) {
36
- this.formatter.success({ fills, cursor: result.cursor });
36
+ this.formatter.success({ cursor: result.cursor, fills });
37
37
  }
38
38
  else {
39
39
  if (fills.length === 0) {
@@ -3,6 +3,7 @@ export default class PortfolioPositions extends BaseCommand {
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  static flags: {
6
+ 'settlement-status': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
7
  json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
8
  };
8
9
  run(): Promise<void>;
@@ -1,3 +1,4 @@
1
+ import { Flags } from '@oclif/core';
1
2
  import chalk from 'chalk';
2
3
  import { BaseCommand } from '../../lib/base-command.js';
3
4
  import { createClientFromConfig } from '../../lib/kalshi/index.js';
@@ -6,18 +7,26 @@ export default class PortfolioPositions extends BaseCommand {
6
7
  static description = 'View current positions with P&L';
7
8
  static examples = [
8
9
  '<%= config.bin %> <%= command.id %>',
10
+ '<%= config.bin %> <%= command.id %> --settlement-status open',
11
+ '<%= config.bin %> <%= command.id %> --settlement-status settled',
9
12
  '<%= config.bin %> <%= command.id %> --json',
10
13
  ];
11
14
  static flags = {
12
15
  ...BaseCommand.baseFlags,
16
+ 'settlement-status': Flags.string({
17
+ description: 'Filter by settlement status',
18
+ options: ['open', 'pending', 'settled'],
19
+ }),
13
20
  };
14
21
  async run() {
15
- await this.parse(PortfolioPositions);
22
+ const { flags } = await this.parse(PortfolioPositions);
16
23
  try {
17
24
  // Create API client from configuration
18
25
  const client = createClientFromConfig();
19
26
  // Fetch positions
20
- const positions = await client.getPositions();
27
+ const positions = await client.getPositions({
28
+ settlement_status: flags['settlement-status'],
29
+ });
21
30
  if (this.formatter.isJSONMode()) {
22
31
  this.formatter.success(positions);
23
32
  }
@@ -4,10 +4,10 @@ import { OutputFormatter } from './output/formatter.js';
4
4
  * Base command class that all kalshitools commands extend
5
5
  */
6
6
  export declare abstract class BaseCommand extends Command {
7
- protected formatter: OutputFormatter;
8
7
  static baseFlags: {
9
8
  json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
9
  };
11
- init(): Promise<void>;
10
+ protected formatter: OutputFormatter;
12
11
  protected catch(error: Error): Promise<unknown>;
12
+ init(): Promise<void>;
13
13
  }
@@ -6,20 +6,15 @@ import { OutputFormatter } from './output/formatter.js';
6
6
  * Base command class that all kalshitools commands extend
7
7
  */
8
8
  export class BaseCommand extends Command {
9
- formatter;
10
9
  static baseFlags = {
11
10
  json: Flags.boolean({
12
- description: 'Output in JSON format',
13
11
  default: false,
12
+ description: 'Output in JSON format',
14
13
  }),
15
14
  };
16
- async init() {
17
- await super.init();
18
- const { flags } = await this.parse(this.constructor);
19
- this.formatter = new OutputFormatter(flags.json, this.id);
20
- }
15
+ formatter;
21
16
  async catch(error) {
22
- logger.error({ error, command: this.id }, 'Command failed');
17
+ logger.error({ command: this.id, error }, 'Command failed');
23
18
  if (error instanceof KalshiToolsError) {
24
19
  if (this.formatter?.isJSONMode()) {
25
20
  this.formatter.error(error.code, error.message, error.details);
@@ -35,4 +30,9 @@ export class BaseCommand extends Command {
35
30
  }
36
31
  throw error;
37
32
  }
33
+ async init() {
34
+ await super.init();
35
+ const { flags } = await this.parse(this.constructor);
36
+ this.formatter = new OutputFormatter(flags.json, this.id);
37
+ }
38
38
  }
@@ -1,45 +1,37 @@
1
- import { type Config, type ApiEnvConfig } from './schema.js';
1
+ import { type ApiEnvConfig, type Config } from './schema.js';
2
2
  /**
3
3
  * Configuration manager for kalshitools
4
4
  */
5
5
  export declare class ConfigManager {
6
- private store;
7
6
  private static instance;
7
+ private store;
8
8
  constructor();
9
9
  /**
10
10
  * Get singleton instance
11
11
  */
12
12
  static getInstance(): ConfigManager;
13
- /**
14
- * Get the full configuration
15
- */
16
- getConfig(): Config;
17
- /**
18
- * Get the current environment (demo or production)
19
- */
20
- getEnvironment(): 'demo' | 'production';
21
- /**
22
- * Set the environment
23
- */
24
- setEnvironment(env: 'demo' | 'production'): void;
25
13
  /**
26
14
  * Get API configuration for the current environment
27
15
  */
28
16
  getApiConfig(): ApiEnvConfig;
29
17
  /**
30
- * Read private key from file
18
+ * Get the full configuration
31
19
  */
32
- readPrivateKey(): string;
20
+ getConfig(): Config;
33
21
  /**
34
- * Set API configuration for an environment
22
+ * Get the configuration file path
35
23
  */
36
- setApiConfig(env: 'demo' | 'production', config: Partial<ApiEnvConfig>): void;
24
+ getConfigPath(): string;
25
+ /**
26
+ * Get the current environment (demo or production)
27
+ */
28
+ getEnvironment(): 'demo' | 'production';
37
29
  /**
38
30
  * Get output configuration
39
31
  */
40
32
  getOutputConfig(): {
41
- defaultFormat: "json" | "table";
42
33
  colors: boolean;
34
+ defaultFormat: "json" | "table";
43
35
  };
44
36
  /**
45
37
  * Get trading configuration
@@ -49,21 +41,29 @@ export declare class ConfigManager {
49
41
  maxOrderSize: number;
50
42
  };
51
43
  /**
52
- * Set a configuration value
44
+ * Check if configuration is initialized
53
45
  */
54
- set<K extends keyof Config>(key: K, value: Config[K]): void;
46
+ isConfigured(): boolean;
55
47
  /**
56
- * Get the configuration file path
48
+ * Read private key from file
57
49
  */
58
- getConfigPath(): string;
50
+ readPrivateKey(): string;
59
51
  /**
60
52
  * Reset configuration to defaults
61
53
  */
62
54
  reset(): void;
63
55
  /**
64
- * Check if configuration is initialized
56
+ * Set a configuration value
65
57
  */
66
- isConfigured(): boolean;
58
+ set<K extends keyof Config>(key: K, value: Config[K]): void;
59
+ /**
60
+ * Set API configuration for an environment
61
+ */
62
+ setApiConfig(env: 'demo' | 'production', config: Partial<ApiEnvConfig>): void;
63
+ /**
64
+ * Set the environment
65
+ */
66
+ setEnvironment(env: 'demo' | 'production'): void;
67
67
  }
68
68
  /**
69
69
  * Get the global configuration manager instance
@@ -1,20 +1,20 @@
1
1
  import Conf from 'conf';
2
+ import { readFileSync } from 'node:fs';
2
3
  import { homedir } from 'node:os';
3
4
  import { join } from 'node:path';
4
- import { readFileSync } from 'node:fs';
5
- import { defaultConfig } from './schema.js';
6
5
  import { ConfigError } from '../errors/base.js';
7
6
  import { logger } from '../logger.js';
7
+ import { defaultConfig } from './schema.js';
8
8
  /**
9
9
  * Configuration manager for kalshitools
10
10
  */
11
11
  export class ConfigManager {
12
- store;
13
12
  static instance = null;
13
+ store;
14
14
  constructor() {
15
15
  this.store = new Conf({
16
- projectName: 'kalshitools',
17
16
  defaults: defaultConfig,
17
+ projectName: 'kalshitools',
18
18
  });
19
19
  }
20
20
  /**
@@ -26,6 +26,24 @@ export class ConfigManager {
26
26
  }
27
27
  return ConfigManager.instance;
28
28
  }
29
+ /**
30
+ * Get API configuration for the current environment
31
+ */
32
+ getApiConfig() {
33
+ const env = this.getEnvironment();
34
+ const config = this.store.get(`api.${env}`);
35
+ // Override with environment variables if present
36
+ const keyId = process.env.KALSHI_API_KEY_ID || config.keyId;
37
+ const privateKeyPath = process.env.KALSHI_PRIVATE_KEY_PATH || config.privateKeyPath;
38
+ if (!keyId || !privateKeyPath) {
39
+ throw new ConfigError(`API credentials not configured for ${env} environment. Run 'kalshitools config init' to set up.`, { environment: env });
40
+ }
41
+ return {
42
+ baseUrl: config.baseUrl,
43
+ keyId,
44
+ privateKeyPath,
45
+ };
46
+ }
29
47
  /**
30
48
  * Get the full configuration
31
49
  */
@@ -33,6 +51,12 @@ export class ConfigManager {
33
51
  const config = this.store.store;
34
52
  return config;
35
53
  }
54
+ /**
55
+ * Get the configuration file path
56
+ */
57
+ getConfigPath() {
58
+ return this.store.path;
59
+ }
36
60
  /**
37
61
  * Get the current environment (demo or production)
38
62
  */
@@ -40,28 +64,24 @@ export class ConfigManager {
40
64
  return process.env.KALSHI_ENV === 'production' ? 'production' : this.store.get('environment', 'demo');
41
65
  }
42
66
  /**
43
- * Set the environment
67
+ * Get output configuration
44
68
  */
45
- setEnvironment(env) {
46
- this.store.set('environment', env);
69
+ getOutputConfig() {
70
+ return this.store.get('output');
47
71
  }
48
72
  /**
49
- * Get API configuration for the current environment
73
+ * Get trading configuration
50
74
  */
51
- getApiConfig() {
75
+ getTradingConfig() {
76
+ return this.store.get('trading');
77
+ }
78
+ /**
79
+ * Check if configuration is initialized
80
+ */
81
+ isConfigured() {
52
82
  const env = this.getEnvironment();
53
83
  const config = this.store.get(`api.${env}`);
54
- // Override with environment variables if present
55
- const keyId = process.env.KALSHI_API_KEY_ID || config.keyId;
56
- const privateKeyPath = process.env.KALSHI_PRIVATE_KEY_PATH || config.privateKeyPath;
57
- if (!keyId || !privateKeyPath) {
58
- throw new ConfigError(`API credentials not configured for ${env} environment. Run 'kalshitools config init' to set up.`, { environment: env });
59
- }
60
- return {
61
- baseUrl: config.baseUrl,
62
- keyId,
63
- privateKeyPath,
64
- };
84
+ return Boolean(config.keyId && config.privateKeyPath);
65
85
  }
66
86
  /**
67
87
  * Read private key from file
@@ -78,29 +98,16 @@ export class ConfigManager {
78
98
  }
79
99
  catch (error) {
80
100
  throw new ConfigError(`Failed to read private key from ${expandedPath}`, {
81
- path: expandedPath,
82
101
  error: error instanceof Error ? error.message : String(error),
102
+ path: expandedPath,
83
103
  });
84
104
  }
85
105
  }
86
106
  /**
87
- * Set API configuration for an environment
88
- */
89
- setApiConfig(env, config) {
90
- const current = this.store.get(`api.${env}`);
91
- this.store.set(`api.${env}`, { ...current, ...config });
92
- }
93
- /**
94
- * Get output configuration
95
- */
96
- getOutputConfig() {
97
- return this.store.get('output');
98
- }
99
- /**
100
- * Get trading configuration
107
+ * Reset configuration to defaults
101
108
  */
102
- getTradingConfig() {
103
- return this.store.get('trading');
109
+ reset() {
110
+ this.store.clear();
104
111
  }
105
112
  /**
106
113
  * Set a configuration value
@@ -109,24 +116,17 @@ export class ConfigManager {
109
116
  this.store.set(key, value);
110
117
  }
111
118
  /**
112
- * Get the configuration file path
113
- */
114
- getConfigPath() {
115
- return this.store.path;
116
- }
117
- /**
118
- * Reset configuration to defaults
119
+ * Set API configuration for an environment
119
120
  */
120
- reset() {
121
- this.store.clear();
121
+ setApiConfig(env, config) {
122
+ const current = this.store.get(`api.${env}`);
123
+ this.store.set(`api.${env}`, { ...current, ...config });
122
124
  }
123
125
  /**
124
- * Check if configuration is initialized
126
+ * Set the environment
125
127
  */
126
- isConfigured() {
127
- const env = this.getEnvironment();
128
- const config = this.store.get(`api.${env}`);
129
- return Boolean(config.keyId && config.privateKeyPath);
128
+ setEnvironment(env) {
129
+ this.store.set('environment', env);
130
130
  }
131
131
  }
132
132
  /**