@newyorkcompute/kalshi-core 0.1.0 → 0.1.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/dist/index.d.ts CHANGED
@@ -6,4 +6,6 @@
6
6
  export { type KalshiConfig, DEFAULT_BASE_PATH, DEMO_BASE_PATH, getKalshiConfig, createSdkConfig, createMarketApi, createPortfolioApi, createOrdersApi, createEventsApi, } from "./config.js";
7
7
  export { formatPrice, formatCurrency, formatPercent, formatPriceChange, formatCompactNumber, formatRelativeTime, truncate, padString, } from "./format.js";
8
8
  export * from "./types.js";
9
+ export { withTimeout, TimeoutError } from "./with-timeout.js";
10
+ export { validateOrder, type OrderValidationInput, type OrderValidationResult, } from "./validate-order.js";
9
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,KAAK,YAAY,EACjB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,eAAe,GAChB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,WAAW,EACX,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,QAAQ,EACR,SAAS,GACV,MAAM,aAAa,CAAC;AAGrB,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,KAAK,YAAY,EACjB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,eAAe,GAChB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,WAAW,EACX,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,QAAQ,EACR,SAAS,GACV,MAAM,aAAa,CAAC;AAGrB,cAAc,YAAY,CAAC;AAG3B,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAG9D,OAAO,EACL,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,GAC3B,MAAM,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -9,4 +9,8 @@ export { DEFAULT_BASE_PATH, DEMO_BASE_PATH, getKalshiConfig, createSdkConfig, cr
9
9
  export { formatPrice, formatCurrency, formatPercent, formatPriceChange, formatCompactNumber, formatRelativeTime, truncate, padString, } from "./format.js";
10
10
  // Types
11
11
  export * from "./types.js";
12
+ // Utilities
13
+ export { withTimeout, TimeoutError } from "./with-timeout.js";
14
+ // Validation
15
+ export { validateOrder, } from "./validate-order.js";
12
16
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,gBAAgB;AAChB,OAAO,EAEL,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,eAAe,GAChB,MAAM,aAAa,CAAC;AAErB,uBAAuB;AACvB,OAAO,EACL,WAAW,EACX,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,QAAQ,EACR,SAAS,GACV,MAAM,aAAa,CAAC;AAErB,QAAQ;AACR,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,gBAAgB;AAChB,OAAO,EAEL,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,eAAe,GAChB,MAAM,aAAa,CAAC;AAErB,uBAAuB;AACvB,OAAO,EACL,WAAW,EACX,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,QAAQ,EACR,SAAS,GACV,MAAM,aAAa,CAAC;AAErB,QAAQ;AACR,cAAc,YAAY,CAAC;AAE3B,YAAY;AACZ,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE9D,aAAa;AACb,OAAO,EACL,aAAa,GAGd,MAAM,qBAAqB,CAAC"}
package/dist/types.d.ts CHANGED
@@ -38,6 +38,7 @@ export interface MarketDisplay {
38
38
  no_bid?: number;
39
39
  no_ask?: number;
40
40
  volume?: number;
41
+ volume_24h?: number;
41
42
  open_interest?: number;
42
43
  close_time?: string;
43
44
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACV,SAAS,EACT,YAAY,EACZ,SAAS,EACT,SAAS,EACT,aAAa,GACd,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,0BAA0B,EAC1B,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC;AAE3B;;GAEG;AACH,MAAM,MAAM,IAAI,GAAG,KAAK,GAAG,IAAI,CAAC;AAEhC;;GAEG;AACH,MAAM,MAAM,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;AAEpC;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE3C;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEzD;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;AAE1E;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,cAAc,EAAE,CAAC;IACtB,EAAE,EAAE,cAAc,EAAE,CAAC;CACtB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACV,SAAS,EACT,YAAY,EACZ,SAAS,EACT,SAAS,EACT,aAAa,GACd,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,0BAA0B,EAC1B,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC;AAE3B;;GAEG;AACH,MAAM,MAAM,IAAI,GAAG,KAAK,GAAG,IAAI,CAAC;AAEhC;;GAEG;AACH,MAAM,MAAM,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;AAEpC;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE3C;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEzD;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;AAE1E;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,cAAc,EAAE,CAAC;IACtB,EAAE,EAAE,cAAc,EAAE,CAAC;CACtB"}
@@ -0,0 +1,32 @@
1
+ import type { MarketApi, PortfolioApi } from "kalshi-typescript";
2
+ export interface OrderValidationInput {
3
+ ticker: string;
4
+ side: "yes" | "no";
5
+ action: "buy" | "sell";
6
+ count: number;
7
+ price?: number;
8
+ }
9
+ export interface OrderValidationResult {
10
+ valid: boolean;
11
+ errors: string[];
12
+ warnings: string[];
13
+ estimatedCost?: number;
14
+ currentBalance?: number;
15
+ marketStatus?: string;
16
+ }
17
+ /**
18
+ * Validates an order before submission
19
+ *
20
+ * Performs pre-flight checks:
21
+ * - Market is open for trading
22
+ * - Sufficient balance for buy orders
23
+ * - Price is reasonable (warns if far from market)
24
+ * - Order quantity is valid
25
+ *
26
+ * @param input - Order parameters to validate
27
+ * @param marketApi - Market API client
28
+ * @param portfolioApi - Portfolio API client
29
+ * @returns Validation result with errors and warnings
30
+ */
31
+ export declare function validateOrder(input: OrderValidationInput, marketApi: MarketApi, portfolioApi: PortfolioApi): Promise<OrderValidationResult>;
32
+ //# sourceMappingURL=validate-order.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-order.d.ts","sourceRoot":"","sources":["../src/validate-order.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC;IACnB,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,oBAAoB,EAC3B,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC,qBAAqB,CAAC,CAqFhC"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Validates an order before submission
3
+ *
4
+ * Performs pre-flight checks:
5
+ * - Market is open for trading
6
+ * - Sufficient balance for buy orders
7
+ * - Price is reasonable (warns if far from market)
8
+ * - Order quantity is valid
9
+ *
10
+ * @param input - Order parameters to validate
11
+ * @param marketApi - Market API client
12
+ * @param portfolioApi - Portfolio API client
13
+ * @returns Validation result with errors and warnings
14
+ */
15
+ export async function validateOrder(input, marketApi, portfolioApi) {
16
+ const errors = [];
17
+ const warnings = [];
18
+ let estimatedCost = 0;
19
+ let currentBalance = 0;
20
+ let marketStatus = "unknown";
21
+ try {
22
+ // 1. Fetch market details
23
+ const marketResponse = await marketApi.getMarket(input.ticker);
24
+ const market = marketResponse.data.market;
25
+ marketStatus = market.status || "unknown";
26
+ // Check market is open
27
+ if (market.status?.toLowerCase() !== "open") {
28
+ errors.push(`Market ${input.ticker} is ${market.status}, not open for trading`);
29
+ }
30
+ // Get current market price
31
+ const currentPrice = input.side === "yes"
32
+ ? input.action === "buy"
33
+ ? market.yes_ask
34
+ : market.yes_bid
35
+ : input.action === "buy"
36
+ ? market.no_ask
37
+ : market.no_bid;
38
+ // Warn if user price is far from market
39
+ if (input.price && currentPrice) {
40
+ const priceDiff = Math.abs(input.price - currentPrice);
41
+ if (priceDiff > 20) {
42
+ warnings.push(`Your price (${input.price}¢) is ${priceDiff}¢ away from market (${currentPrice}¢)`);
43
+ }
44
+ }
45
+ // 2. Fetch balance
46
+ const balanceResponse = await portfolioApi.getBalance();
47
+ currentBalance = balanceResponse.data.balance || 0;
48
+ // Calculate estimated cost
49
+ // For buy orders: cost = count * price
50
+ // For sell orders: no cost (you receive money)
51
+ if (input.action === "buy") {
52
+ const price = input.price || currentPrice || 50; // Default to 50¢ if unknown
53
+ estimatedCost = input.count * price;
54
+ // Check sufficient balance
55
+ if (estimatedCost > currentBalance) {
56
+ errors.push(`Insufficient balance: need ${estimatedCost}¢, have ${currentBalance}¢`);
57
+ }
58
+ }
59
+ // 3. Sanity checks
60
+ if (input.count <= 0) {
61
+ errors.push("Order quantity must be positive");
62
+ }
63
+ if (input.count > 1000) {
64
+ warnings.push("Large order size may have poor execution");
65
+ }
66
+ if (input.price && (input.price < 1 || input.price > 99)) {
67
+ errors.push("Price must be between 1¢ and 99¢");
68
+ }
69
+ }
70
+ catch (error) {
71
+ errors.push(`Validation failed: ${error instanceof Error ? error.message : "Unknown error"}`);
72
+ }
73
+ return {
74
+ valid: errors.length === 0,
75
+ errors,
76
+ warnings,
77
+ estimatedCost,
78
+ currentBalance,
79
+ marketStatus,
80
+ };
81
+ }
82
+ //# sourceMappingURL=validate-order.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-order.js","sourceRoot":"","sources":["../src/validate-order.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=validate-order.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-order.test.d.ts","sourceRoot":"","sources":["../src/validate-order.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,234 @@
1
+ import { describe, it, expect, vi } from "vitest";
2
+ import { validateOrder } from "./validate-order.js";
3
+ describe("validateOrder", () => {
4
+ const mockGetMarket = vi.fn();
5
+ const mockGetBalance = vi.fn();
6
+ const mockMarketApi = {
7
+ getMarket: mockGetMarket,
8
+ };
9
+ const mockPortfolioApi = {
10
+ getBalance: mockGetBalance,
11
+ };
12
+ it("should validate successful order", async () => {
13
+ mockGetMarket.mockResolvedValue({
14
+ data: {
15
+ market: {
16
+ ticker: "TEST-MARKET",
17
+ status: "open",
18
+ yes_ask: 50,
19
+ yes_bid: 48,
20
+ },
21
+ },
22
+ });
23
+ mockGetBalance.mockResolvedValue({
24
+ data: { balance: 10000 },
25
+ });
26
+ const result = await validateOrder({
27
+ ticker: "TEST-MARKET",
28
+ side: "yes",
29
+ action: "buy",
30
+ count: 10,
31
+ price: 50,
32
+ }, mockMarketApi, mockPortfolioApi);
33
+ expect(result.valid).toBe(true);
34
+ expect(result.errors).toHaveLength(0);
35
+ expect(result.estimatedCost).toBe(500);
36
+ });
37
+ it("should reject order on closed market", async () => {
38
+ mockGetMarket.mockResolvedValue({
39
+ data: {
40
+ market: {
41
+ ticker: "TEST-MARKET",
42
+ status: "closed",
43
+ },
44
+ },
45
+ });
46
+ mockGetBalance.mockResolvedValue({
47
+ data: { balance: 10000 },
48
+ });
49
+ const result = await validateOrder({
50
+ ticker: "TEST-MARKET",
51
+ side: "yes",
52
+ action: "buy",
53
+ count: 10,
54
+ price: 50,
55
+ }, mockMarketApi, mockPortfolioApi);
56
+ expect(result.valid).toBe(false);
57
+ expect(result.errors.some((e) => e.includes("closed"))).toBe(true);
58
+ });
59
+ it("should reject order with insufficient balance", async () => {
60
+ mockGetMarket.mockResolvedValue({
61
+ data: {
62
+ market: {
63
+ ticker: "TEST-MARKET",
64
+ status: "open",
65
+ yes_ask: 50,
66
+ },
67
+ },
68
+ });
69
+ mockGetBalance.mockResolvedValue({
70
+ data: { balance: 100 }, // Only 100¢
71
+ });
72
+ const result = await validateOrder({
73
+ ticker: "TEST-MARKET",
74
+ side: "yes",
75
+ action: "buy",
76
+ count: 10,
77
+ price: 50, // Costs 500¢
78
+ }, mockMarketApi, mockPortfolioApi);
79
+ expect(result.valid).toBe(false);
80
+ expect(result.errors.some((e) => e.includes("Insufficient balance"))).toBe(true);
81
+ });
82
+ it("should warn on price far from market", async () => {
83
+ mockGetMarket.mockResolvedValue({
84
+ data: {
85
+ market: {
86
+ ticker: "TEST-MARKET",
87
+ status: "open",
88
+ yes_ask: 50,
89
+ },
90
+ },
91
+ });
92
+ mockGetBalance.mockResolvedValue({
93
+ data: { balance: 10000 },
94
+ });
95
+ const result = await validateOrder({
96
+ ticker: "TEST-MARKET",
97
+ side: "yes",
98
+ action: "buy",
99
+ count: 10,
100
+ price: 80, // 30¢ away from market
101
+ }, mockMarketApi, mockPortfolioApi);
102
+ expect(result.valid).toBe(true);
103
+ expect(result.warnings.length).toBeGreaterThan(0);
104
+ expect(result.warnings.some((w) => w.includes("away from market"))).toBe(true);
105
+ });
106
+ it("should reject negative quantity", async () => {
107
+ mockGetMarket.mockResolvedValue({
108
+ data: {
109
+ market: {
110
+ ticker: "TEST-MARKET",
111
+ status: "open",
112
+ yes_ask: 50,
113
+ },
114
+ },
115
+ });
116
+ mockGetBalance.mockResolvedValue({
117
+ data: { balance: 10000 },
118
+ });
119
+ const result = await validateOrder({
120
+ ticker: "TEST-MARKET",
121
+ side: "yes",
122
+ action: "buy",
123
+ count: -5,
124
+ price: 50,
125
+ }, mockMarketApi, mockPortfolioApi);
126
+ expect(result.valid).toBe(false);
127
+ expect(result.errors).toContain("Order quantity must be positive");
128
+ });
129
+ it("should warn on large order size", async () => {
130
+ mockGetMarket.mockResolvedValue({
131
+ data: {
132
+ market: {
133
+ ticker: "TEST-MARKET",
134
+ status: "open",
135
+ yes_ask: 50,
136
+ },
137
+ },
138
+ });
139
+ mockGetBalance.mockResolvedValue({
140
+ data: { balance: 100000 },
141
+ });
142
+ const result = await validateOrder({
143
+ ticker: "TEST-MARKET",
144
+ side: "yes",
145
+ action: "buy",
146
+ count: 1500,
147
+ price: 50,
148
+ }, mockMarketApi, mockPortfolioApi);
149
+ expect(result.valid).toBe(true);
150
+ expect(result.warnings).toContain("Large order size may have poor execution");
151
+ });
152
+ it("should reject invalid price range", async () => {
153
+ mockGetMarket.mockResolvedValue({
154
+ data: {
155
+ market: {
156
+ ticker: "TEST-MARKET",
157
+ status: "open",
158
+ yes_ask: 50,
159
+ },
160
+ },
161
+ });
162
+ mockGetBalance.mockResolvedValue({
163
+ data: { balance: 10000 },
164
+ });
165
+ const result = await validateOrder({
166
+ ticker: "TEST-MARKET",
167
+ side: "yes",
168
+ action: "buy",
169
+ count: 10,
170
+ price: 150, // Invalid: >99
171
+ }, mockMarketApi, mockPortfolioApi);
172
+ expect(result.valid).toBe(false);
173
+ expect(result.errors).toContain("Price must be between 1¢ and 99¢");
174
+ });
175
+ it("should allow sell orders without balance check", async () => {
176
+ mockGetMarket.mockResolvedValue({
177
+ data: {
178
+ market: {
179
+ ticker: "TEST-MARKET",
180
+ status: "open",
181
+ yes_bid: 50,
182
+ },
183
+ },
184
+ });
185
+ mockGetBalance.mockResolvedValue({
186
+ data: { balance: 0 }, // No balance
187
+ });
188
+ const result = await validateOrder({
189
+ ticker: "TEST-MARKET",
190
+ side: "yes",
191
+ action: "sell",
192
+ count: 10,
193
+ price: 50,
194
+ }, mockMarketApi, mockPortfolioApi);
195
+ expect(result.valid).toBe(true);
196
+ expect(result.estimatedCost).toBe(0);
197
+ });
198
+ it("should handle API errors gracefully", async () => {
199
+ mockGetMarket.mockRejectedValue(new Error("Network error"));
200
+ const result = await validateOrder({
201
+ ticker: "TEST-MARKET",
202
+ side: "yes",
203
+ action: "buy",
204
+ count: 10,
205
+ price: 50,
206
+ }, mockMarketApi, mockPortfolioApi);
207
+ expect(result.valid).toBe(false);
208
+ expect(result.errors.some((e) => e.includes("Validation failed"))).toBe(true);
209
+ });
210
+ it("should use default price if not provided", async () => {
211
+ mockGetMarket.mockResolvedValue({
212
+ data: {
213
+ market: {
214
+ ticker: "TEST-MARKET",
215
+ status: "open",
216
+ yes_ask: 60,
217
+ },
218
+ },
219
+ });
220
+ mockGetBalance.mockResolvedValue({
221
+ data: { balance: 10000 },
222
+ });
223
+ const result = await validateOrder({
224
+ ticker: "TEST-MARKET",
225
+ side: "yes",
226
+ action: "buy",
227
+ count: 10,
228
+ // No price provided
229
+ }, mockMarketApi, mockPortfolioApi);
230
+ expect(result.valid).toBe(true);
231
+ expect(result.estimatedCost).toBe(600); // Uses market price (60)
232
+ });
233
+ });
234
+ //# sourceMappingURL=validate-order.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-order.test.js","sourceRoot":"","sources":["../src/validate-order.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Custom error class for timeout errors
3
+ */
4
+ export declare class TimeoutError extends Error {
5
+ constructor(message: string);
6
+ }
7
+ /**
8
+ * Wraps a promise with a timeout
9
+ *
10
+ * @param promise - The promise to wrap
11
+ * @param timeoutMs - Timeout in milliseconds
12
+ * @param errorMessage - Custom error message for timeout
13
+ * @returns The promise result or throws TimeoutError
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const result = await withTimeout(
18
+ * fetch('https://api.example.com'),
19
+ * 5000,
20
+ * 'API request timed out'
21
+ * );
22
+ * ```
23
+ */
24
+ export declare function withTimeout<T>(promise: Promise<T>, timeoutMs: number, errorMessage?: string): Promise<T>;
25
+ //# sourceMappingURL=with-timeout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"with-timeout.d.ts","sourceRoot":"","sources":["../src/with-timeout.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,WAAW,CAAC,CAAC,EACjC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,SAAS,EAAE,MAAM,EACjB,YAAY,SAAoB,GAC/B,OAAO,CAAC,CAAC,CAAC,CAMZ"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Custom error class for timeout errors
3
+ */
4
+ export class TimeoutError extends Error {
5
+ constructor(message) {
6
+ super(message);
7
+ this.name = "TimeoutError";
8
+ }
9
+ }
10
+ /**
11
+ * Wraps a promise with a timeout
12
+ *
13
+ * @param promise - The promise to wrap
14
+ * @param timeoutMs - Timeout in milliseconds
15
+ * @param errorMessage - Custom error message for timeout
16
+ * @returns The promise result or throws TimeoutError
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * const result = await withTimeout(
21
+ * fetch('https://api.example.com'),
22
+ * 5000,
23
+ * 'API request timed out'
24
+ * );
25
+ * ```
26
+ */
27
+ export async function withTimeout(promise, timeoutMs, errorMessage = "Request timeout") {
28
+ const timeout = new Promise((_, reject) => {
29
+ setTimeout(() => reject(new TimeoutError(errorMessage)), timeoutMs);
30
+ });
31
+ return Promise.race([promise, timeout]);
32
+ }
33
+ //# sourceMappingURL=with-timeout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"with-timeout.js","sourceRoot":"","sources":["../src/with-timeout.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,YAAa,SAAQ,KAAK;IACrC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,OAAmB,EACnB,SAAiB,EACjB,YAAY,GAAG,iBAAiB;IAEhC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;QAC/C,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,YAAY,CAAC,YAAY,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=with-timeout.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"with-timeout.test.d.ts","sourceRoot":"","sources":["../src/with-timeout.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,72 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
+ import { withTimeout, TimeoutError } from "./with-timeout.js";
3
+ describe("withTimeout", () => {
4
+ beforeEach(() => {
5
+ vi.useFakeTimers();
6
+ });
7
+ afterEach(() => {
8
+ vi.useRealTimers();
9
+ });
10
+ it("should resolve if promise completes before timeout", async () => {
11
+ const promise = Promise.resolve("success");
12
+ const resultPromise = withTimeout(promise, 1000);
13
+ const result = await resultPromise;
14
+ expect(result).toBe("success");
15
+ });
16
+ it("should reject with TimeoutError if promise takes too long", async () => {
17
+ const promise = new Promise((resolve) => {
18
+ setTimeout(() => resolve("too late"), 2000);
19
+ });
20
+ const resultPromise = withTimeout(promise, 100, "Custom timeout message");
21
+ vi.advanceTimersByTime(100);
22
+ await expect(resultPromise).rejects.toThrow(TimeoutError);
23
+ await expect(resultPromise).rejects.toThrow("Custom timeout message");
24
+ });
25
+ it("should reject with original error if promise rejects", async () => {
26
+ const promise = Promise.reject(new Error("Network error"));
27
+ await expect(withTimeout(promise, 1000)).rejects.toThrow("Network error");
28
+ });
29
+ it("should use default error message if not provided", async () => {
30
+ const promise = new Promise((resolve) => {
31
+ setTimeout(() => resolve("too late"), 2000);
32
+ });
33
+ const resultPromise = withTimeout(promise, 100);
34
+ vi.advanceTimersByTime(100);
35
+ await expect(resultPromise).rejects.toThrow("Request timeout");
36
+ });
37
+ it("should handle promise that resolves exactly at timeout", async () => {
38
+ let resolvePromise;
39
+ const promise = new Promise((resolve) => {
40
+ resolvePromise = resolve;
41
+ });
42
+ const resultPromise = withTimeout(promise, 1000);
43
+ // Resolve just before timeout
44
+ vi.advanceTimersByTime(999);
45
+ resolvePromise("just in time");
46
+ const result = await resultPromise;
47
+ expect(result).toBe("just in time");
48
+ });
49
+ it("should handle different data types", async () => {
50
+ const numberPromise = Promise.resolve(42);
51
+ expect(await withTimeout(numberPromise, 1000)).toBe(42);
52
+ const objectPromise = Promise.resolve({ foo: "bar" });
53
+ expect(await withTimeout(objectPromise, 1000)).toEqual({ foo: "bar" });
54
+ const arrayPromise = Promise.resolve([1, 2, 3]);
55
+ expect(await withTimeout(arrayPromise, 1000)).toEqual([1, 2, 3]);
56
+ });
57
+ it("should have correct error name", async () => {
58
+ const promise = new Promise((resolve) => {
59
+ setTimeout(() => resolve("too late"), 2000);
60
+ });
61
+ const resultPromise = withTimeout(promise, 100);
62
+ vi.advanceTimersByTime(100);
63
+ try {
64
+ await resultPromise;
65
+ }
66
+ catch (error) {
67
+ expect(error).toBeInstanceOf(TimeoutError);
68
+ expect(error.name).toBe("TimeoutError");
69
+ }
70
+ });
71
+ });
72
+ //# sourceMappingURL=with-timeout.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"with-timeout.test.js","sourceRoot":"","sources":["../src/with-timeout.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE9D,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QAClE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC3C,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAEjD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YACtC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,EAAE,GAAG,EAAE,wBAAwB,CAAC,CAAC;QAE1E,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAE5B,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAC1D,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;QAE3D,MAAM,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YACtC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAEhD,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAE5B,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACtE,IAAI,cAAuC,CAAC;QAC5C,MAAM,OAAO,GAAG,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;YAC9C,cAAc,GAAG,OAAO,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEH,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAEjD,8BAA8B;QAC9B,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAC5B,cAAe,CAAC,cAAc,CAAC,CAAC;QAEhC,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,WAAW,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAExD,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;QACtD,MAAM,CAAC,MAAM,WAAW,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;QAEvE,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAChD,MAAM,CAAC,MAAM,WAAW,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YACtC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAChD,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAE5B,IAAI,CAAC;YACH,MAAM,aAAa,CAAC;QACtB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;YAC3C,MAAM,CAAE,KAAsB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newyorkcompute/kalshi-core",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Shared utilities for Kalshi prediction market tools — SDK configuration, formatting, and types",
5
5
  "author": "NewYorkCompute",
6
6
  "license": "MIT",
@@ -52,4 +52,3 @@
52
52
  "vitest": "^3.2.3"
53
53
  }
54
54
  }
55
-