@newyorkcompute/kalshi-tui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +105 -0
- package/dist/App.d.ts +5 -0
- package/dist/App.d.ts.map +1 -0
- package/dist/App.js +49 -0
- package/dist/App.js.map +1 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +64 -0
- package/dist/cli.js.map +1 -0
- package/dist/components/Header.d.ts +5 -0
- package/dist/components/Header.d.ts.map +1 -0
- package/dist/components/Header.js +14 -0
- package/dist/components/Header.js.map +1 -0
- package/dist/components/HelpModal.d.ts +5 -0
- package/dist/components/HelpModal.d.ts.map +1 -0
- package/dist/components/HelpModal.js +19 -0
- package/dist/components/HelpModal.js.map +1 -0
- package/dist/components/MarketList.d.ts +5 -0
- package/dist/components/MarketList.d.ts.map +1 -0
- package/dist/components/MarketList.js +68 -0
- package/dist/components/MarketList.js.map +1 -0
- package/dist/components/OrderEntry.d.ts +9 -0
- package/dist/components/OrderEntry.d.ts.map +1 -0
- package/dist/components/OrderEntry.js +77 -0
- package/dist/components/OrderEntry.js.map +1 -0
- package/dist/components/Orderbook.d.ts +9 -0
- package/dist/components/Orderbook.d.ts.map +1 -0
- package/dist/components/Orderbook.js +43 -0
- package/dist/components/Orderbook.js.map +1 -0
- package/dist/components/Positions.d.ts +5 -0
- package/dist/components/Positions.d.ts.map +1 -0
- package/dist/components/Positions.js +22 -0
- package/dist/components/Positions.js.map +1 -0
- package/dist/components/SearchBar.d.ts +5 -0
- package/dist/components/SearchBar.d.ts.map +1 -0
- package/dist/components/SearchBar.js +27 -0
- package/dist/components/SearchBar.js.map +1 -0
- package/dist/components/StatusBar.d.ts +5 -0
- package/dist/components/StatusBar.d.ts.map +1 -0
- package/dist/components/StatusBar.js +9 -0
- package/dist/components/StatusBar.js.map +1 -0
- package/dist/components/index.d.ts +11 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +12 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/ui/Box.d.ts +14 -0
- package/dist/components/ui/Box.d.ts.map +1 -0
- package/dist/components/ui/Box.js +9 -0
- package/dist/components/ui/Box.js.map +1 -0
- package/dist/components/ui/Sparkline.d.ts +11 -0
- package/dist/components/ui/Sparkline.d.ts.map +1 -0
- package/dist/components/ui/Sparkline.js +32 -0
- package/dist/components/ui/Sparkline.js.map +1 -0
- package/dist/hooks/index.d.ts +5 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +5 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/useKalshi.d.ts +16 -0
- package/dist/hooks/useKalshi.d.ts.map +1 -0
- package/dist/hooks/useKalshi.js +31 -0
- package/dist/hooks/useKalshi.js.map +1 -0
- package/dist/hooks/useMarkets.d.ts +13 -0
- package/dist/hooks/useMarkets.d.ts.map +1 -0
- package/dist/hooks/useMarkets.js +89 -0
- package/dist/hooks/useMarkets.js.map +1 -0
- package/dist/hooks/useOrderbook.d.ts +13 -0
- package/dist/hooks/useOrderbook.d.ts.map +1 -0
- package/dist/hooks/useOrderbook.js +81 -0
- package/dist/hooks/useOrderbook.js.map +1 -0
- package/dist/hooks/usePortfolio.d.ts +18 -0
- package/dist/hooks/usePortfolio.d.ts.map +1 -0
- package/dist/hooks/usePortfolio.js +84 -0
- package/dist/hooks/usePortfolio.js.map +1 -0
- package/dist/stores/app-store.d.ts +17 -0
- package/dist/stores/app-store.d.ts.map +1 -0
- package/dist/stores/app-store.js +21 -0
- package/dist/stores/app-store.js.map +1 -0
- package/dist/theme.d.ts +31 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +37 -0
- package/dist/theme.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import { formatCurrency, truncate } from "@newyorkcompute/kalshi-core";
|
|
4
|
+
import { usePortfolio } from "../hooks/usePortfolio.js";
|
|
5
|
+
import { useAppStore } from "../stores/app-store.js";
|
|
6
|
+
/**
|
|
7
|
+
* Positions panel showing current holdings
|
|
8
|
+
*/
|
|
9
|
+
export function Positions() {
|
|
10
|
+
const { positions, isLoading, error } = usePortfolio();
|
|
11
|
+
const activePanel = useAppStore((state) => state.activePanel);
|
|
12
|
+
const isActive = activePanel === "positions";
|
|
13
|
+
// Calculate total exposure
|
|
14
|
+
const totalExposure = positions.reduce((sum, pos) => sum + pos.market_exposure, 0);
|
|
15
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: isActive ? "green" : "gray", height: 10, children: [_jsxs(Box, { paddingX: 1, justifyContent: "space-between", children: [_jsx(Text, { bold: true, color: isActive ? "green" : "white", children: "POSITIONS" }), _jsx(Text, { color: "gray", dimColor: true, children: "[F3]" })] }), _jsx(Box, { paddingX: 1, children: _jsx(Text, { color: "gray", children: "─".repeat(40) }) }), _jsxs(Box, { flexDirection: "column", paddingX: 1, flexGrow: 1, children: [isLoading && _jsx(Text, { color: "gray", children: "Loading positions..." }), error && _jsx(Text, { color: "red", children: error }), !isLoading && !error && positions.length === 0 && (_jsx(Text, { color: "gray", children: "No open positions" })), positions.slice(0, 4).map((position) => {
|
|
16
|
+
const side = position.position > 0 ? "YES" : "NO";
|
|
17
|
+
const quantity = Math.abs(position.position);
|
|
18
|
+
const exposure = position.market_exposure;
|
|
19
|
+
return (_jsxs(Box, { justifyContent: "space-between", children: [_jsx(Text, { color: "white", children: truncate(position.ticker, 18) }), _jsxs(Box, { children: [_jsxs(Text, { color: side === "YES" ? "green" : "red", children: [side === "YES" ? "+" : "-", quantity] }), _jsxs(Text, { color: "gray", children: [" ", side] })] }), _jsx(Text, { color: "white", children: formatCurrency(exposure) })] }, position.ticker));
|
|
20
|
+
}), positions.length > 0 && (_jsxs(Box, { marginTop: 1, justifyContent: "space-between", children: [_jsx(Text, { color: "gray", children: "Total Exposure:" }), _jsx(Text, { color: "white", bold: true, children: formatCurrency(totalExposure) })] }))] })] }));
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=Positions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Positions.js","sourceRoot":"","sources":["../../src/components/Positions.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SearchBar.d.ts","sourceRoot":"","sources":["../../src/components/SearchBar.tsx"],"names":[],"mappings":"AAKA;;GAEG;AACH,wBAAgB,SAAS,mDAyCxB"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text, useInput } from "ink";
|
|
3
|
+
import { TextInput } from "@inkjs/ui";
|
|
4
|
+
import { useAppStore } from "../stores/app-store.js";
|
|
5
|
+
/**
|
|
6
|
+
* Search bar for filtering markets
|
|
7
|
+
*/
|
|
8
|
+
export function SearchBar() {
|
|
9
|
+
const isSearching = useAppStore((state) => state.isSearching);
|
|
10
|
+
const setIsSearching = useAppStore((state) => state.setIsSearching);
|
|
11
|
+
const searchQuery = useAppStore((state) => state.searchQuery);
|
|
12
|
+
const setSearchQuery = useAppStore((state) => state.setSearchQuery);
|
|
13
|
+
// Toggle search with /
|
|
14
|
+
useInput((input, key) => {
|
|
15
|
+
if (!isSearching && input === "/") {
|
|
16
|
+
setIsSearching(true);
|
|
17
|
+
}
|
|
18
|
+
if (isSearching && key.escape) {
|
|
19
|
+
setIsSearching(false);
|
|
20
|
+
setSearchQuery("");
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
if (!isSearching && !searchQuery)
|
|
24
|
+
return null;
|
|
25
|
+
return (_jsxs(Box, { borderStyle: "single", borderColor: "green", paddingX: 1, children: [_jsx(Text, { color: "green", children: "/" }), _jsx(Text, { children: " " }), isSearching ? (_jsx(TextInput, { defaultValue: searchQuery, onChange: setSearchQuery, onSubmit: () => setIsSearching(false), placeholder: "Search markets..." })) : (_jsx(Text, { color: "white", children: searchQuery })), searchQuery && (_jsxs(Text, { color: "gray", dimColor: true, children: [" ", "(Esc to clear)"] }))] }));
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=SearchBar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SearchBar.js","sourceRoot":"","sources":["../../src/components/SearchBar.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD;;GAEG;AACH,MAAM,UAAU,SAAS;IACvB,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC9D,MAAM,cAAc,GAAG,WAAW,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IACpE,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC9D,MAAM,cAAc,GAAG,WAAW,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAEpE,uBAAuB;IACvB,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,CAAC,WAAW,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YAClC,cAAc,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;QACD,IAAI,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YAC9B,cAAc,CAAC,KAAK,CAAC,CAAC;YACtB,cAAc,CAAC,EAAE,CAAC,CAAC;QACrB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAE9C,OAAO,CACL,MAAC,GAAG,IAAC,WAAW,EAAC,QAAQ,EAAC,WAAW,EAAC,OAAO,EAAC,QAAQ,EAAE,CAAC,aACvD,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,kBAAS,EAC5B,KAAC,IAAI,oBAAS,EACb,WAAW,CAAC,CAAC,CAAC,CACb,KAAC,SAAS,IACR,YAAY,EAAE,WAAW,EACzB,QAAQ,EAAE,cAAc,EACxB,QAAQ,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,EACrC,WAAW,EAAC,mBAAmB,GAC/B,CACH,CAAC,CAAC,CAAC,CACF,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,YAAE,WAAW,GAAQ,CACzC,EACA,WAAW,IAAI,CACd,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,QAAQ,mBACxB,GAAG,sBAEC,CACR,IACG,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusBar.d.ts","sourceRoot":"","sources":["../../src/components/StatusBar.tsx"],"names":[],"mappings":"AAGA;;GAEG;AACH,wBAAgB,SAAS,4CAwBxB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
/**
|
|
4
|
+
* Status bar with keybindings and NYC branding
|
|
5
|
+
*/
|
|
6
|
+
export function StatusBar() {
|
|
7
|
+
return (_jsxs(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, justifyContent: "space-between", children: [_jsxs(Box, { children: [_jsx(Text, { color: "gray", children: "Built by " }), _jsx(Text, { color: "white", children: "New York Compute" }), _jsx(Text, { color: "gray", children: " \u2022 " }), _jsx(Text, { color: "green", children: "newyorkcompute.xyz" })] }), _jsxs(Box, { children: [_jsx(Text, { color: "gray", children: "[?] Help" }), _jsx(Text, { color: "gray", children: " " }), _jsx(Text, { color: "gray", children: "[q] Quit" })] })] }));
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=StatusBar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusBar.js","sourceRoot":"","sources":["../../src/components/StatusBar.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC;;GAEG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,CACL,MAAC,GAAG,IACF,WAAW,EAAC,QAAQ,EACpB,WAAW,EAAC,MAAM,EAClB,QAAQ,EAAE,CAAC,EACX,cAAc,EAAC,eAAe,aAG9B,MAAC,GAAG,eACF,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,0BAAiB,EACnC,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,iCAAwB,EAC3C,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,yBAAW,EAC7B,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,mCAA0B,IACzC,EAGN,MAAC,GAAG,eACF,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,yBAAgB,EAClC,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,kBAAS,EAC3B,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,yBAAgB,IAC9B,IACF,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { Header } from "./Header.js";
|
|
2
|
+
export { MarketList } from "./MarketList.js";
|
|
3
|
+
export { Orderbook } from "./Orderbook.js";
|
|
4
|
+
export { Positions } from "./Positions.js";
|
|
5
|
+
export { OrderEntry } from "./OrderEntry.js";
|
|
6
|
+
export { StatusBar } from "./StatusBar.js";
|
|
7
|
+
export { HelpModal } from "./HelpModal.js";
|
|
8
|
+
export { SearchBar } from "./SearchBar.js";
|
|
9
|
+
export { Panel } from "./ui/Box.js";
|
|
10
|
+
export { Sparkline } from "./ui/Sparkline.js";
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { Header } from "./Header.js";
|
|
2
|
+
export { MarketList } from "./MarketList.js";
|
|
3
|
+
export { Orderbook } from "./Orderbook.js";
|
|
4
|
+
export { Positions } from "./Positions.js";
|
|
5
|
+
export { OrderEntry } from "./OrderEntry.js";
|
|
6
|
+
export { StatusBar } from "./StatusBar.js";
|
|
7
|
+
export { HelpModal } from "./HelpModal.js";
|
|
8
|
+
export { SearchBar } from "./SearchBar.js";
|
|
9
|
+
// UI components
|
|
10
|
+
export { Panel } from "./ui/Box.js";
|
|
11
|
+
export { Sparkline } from "./ui/Sparkline.js";
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,gBAAgB;AAChB,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { BoxProps as InkBoxProps } from "ink";
|
|
3
|
+
interface PanelProps extends InkBoxProps {
|
|
4
|
+
title?: string;
|
|
5
|
+
titleRight?: string;
|
|
6
|
+
isActive?: boolean;
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Styled panel component following NYC design guidelines
|
|
11
|
+
*/
|
|
12
|
+
export declare function Panel({ title, titleRight, isActive, children, ...props }: PanelProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=Box.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Box.d.ts","sourceRoot":"","sources":["../../../src/components/ui/Box.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,QAAQ,IAAI,WAAW,EAAE,MAAM,KAAK,CAAC;AAEnD,UAAU,UAAW,SAAQ,WAAW;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,UAAU,EACV,QAAgB,EAChB,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,UAAU,2CAqCZ"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box as InkBox, Text } from "ink";
|
|
3
|
+
/**
|
|
4
|
+
* Styled panel component following NYC design guidelines
|
|
5
|
+
*/
|
|
6
|
+
export function Panel({ title, titleRight, isActive = false, children, ...props }) {
|
|
7
|
+
return (_jsxs(InkBox, { flexDirection: "column", borderStyle: "single", borderColor: isActive ? "green" : "gray", ...props, children: [(title || titleRight) && (_jsxs(InkBox, { paddingX: 1, justifyContent: "space-between", children: [title && (_jsx(Text, { bold: true, color: isActive ? "green" : "white", children: title })), titleRight && (_jsx(Text, { color: "gray", dimColor: true, children: titleRight }))] })), title && (_jsx(InkBox, { paddingX: 1, children: _jsx(Text, { color: "gray", children: "─".repeat(40) }) })), _jsx(InkBox, { flexDirection: "column", paddingX: 1, flexGrow: 1, children: children })] }));
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=Box.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Box.js","sourceRoot":"","sources":["../../../src/components/ui/Box.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,IAAI,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAU1C;;GAEG;AACH,MAAM,UAAU,KAAK,CAAC,EACpB,KAAK,EACL,UAAU,EACV,QAAQ,GAAG,KAAK,EAChB,QAAQ,EACR,GAAG,KAAK,EACG;IACX,OAAO,CACL,MAAC,MAAM,IACL,aAAa,EAAC,QAAQ,EACtB,WAAW,EAAC,QAAQ,EACpB,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,KACpC,KAAK,aAGR,CAAC,KAAK,IAAI,UAAU,CAAC,IAAI,CACxB,MAAC,MAAM,IAAC,QAAQ,EAAE,CAAC,EAAE,cAAc,EAAC,eAAe,aAChD,KAAK,IAAI,CACR,KAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,YAC3C,KAAK,GACD,CACR,EACA,UAAU,IAAI,CACb,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,QAAQ,kBACxB,UAAU,GACN,CACR,IACM,CACV,EAGA,KAAK,IAAI,CACR,KAAC,MAAM,IAAC,QAAQ,EAAE,CAAC,YACjB,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAQ,GACnC,CACV,EAGD,KAAC,MAAM,IAAC,aAAa,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,YACpD,QAAQ,GACF,IACF,CACV,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface SparklineProps {
|
|
2
|
+
data: number[];
|
|
3
|
+
width?: number;
|
|
4
|
+
color?: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Sparkline component for visualizing price history
|
|
8
|
+
*/
|
|
9
|
+
export declare function Sparkline({ data, width, color }: SparklineProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=Sparkline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Sparkline.d.ts","sourceRoot":"","sources":["../../../src/components/ui/Sparkline.tsx"],"names":[],"mappings":"AAGA,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD;;GAEG;AACH,wBAAgB,SAAS,CAAC,EAAE,IAAI,EAAE,KAAU,EAAE,KAAe,EAAE,EAAE,cAAc,2CA2B9E"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Text } from "ink";
|
|
3
|
+
// Sparkline characters (in order of fill level)
|
|
4
|
+
const SPARK_CHARS = ["▁", "▂", "▃", "▄", "▅", "▆", "▇", "█"];
|
|
5
|
+
/**
|
|
6
|
+
* Sparkline component for visualizing price history
|
|
7
|
+
*/
|
|
8
|
+
export function Sparkline({ data, width = 10, color = "green" }) {
|
|
9
|
+
if (data.length === 0) {
|
|
10
|
+
return _jsx(Text, { color: "gray", children: "─".repeat(width) });
|
|
11
|
+
}
|
|
12
|
+
// Normalize data to fit in sparkline range
|
|
13
|
+
const min = Math.min(...data);
|
|
14
|
+
const max = Math.max(...data);
|
|
15
|
+
const range = max - min || 1;
|
|
16
|
+
// Sample data to fit width
|
|
17
|
+
const sampledData = [];
|
|
18
|
+
for (let i = 0; i < width; i++) {
|
|
19
|
+
const index = Math.floor((i / width) * data.length);
|
|
20
|
+
sampledData.push(data[index]);
|
|
21
|
+
}
|
|
22
|
+
// Convert to sparkline characters
|
|
23
|
+
const sparkline = sampledData
|
|
24
|
+
.map((value) => {
|
|
25
|
+
const normalized = (value - min) / range;
|
|
26
|
+
const charIndex = Math.floor(normalized * (SPARK_CHARS.length - 1));
|
|
27
|
+
return SPARK_CHARS[charIndex];
|
|
28
|
+
})
|
|
29
|
+
.join("");
|
|
30
|
+
return _jsx(Text, { color: color, children: sparkline });
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=Sparkline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Sparkline.js","sourceRoot":"","sources":["../../../src/components/ui/Sparkline.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAQ3B,gDAAgD;AAChD,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAE7D;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,EAAE,IAAI,EAAE,KAAK,GAAG,EAAE,EAAE,KAAK,GAAG,OAAO,EAAkB;IAC7E,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAE,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAQ,CAAC;IACvD,CAAC;IAED,2CAA2C;IAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IAC9B,MAAM,KAAK,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC;IAE7B,2BAA2B;IAC3B,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;QACpD,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAChC,CAAC;IAED,kCAAkC;IAClC,MAAM,SAAS,GAAG,WAAW;SAC1B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACb,MAAM,UAAU,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC;QACzC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QACpE,OAAO,WAAW,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;IAEZ,OAAO,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,YAAG,SAAS,GAAQ,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type KalshiConfig } from "@newyorkcompute/kalshi-core";
|
|
2
|
+
import type { MarketApi, PortfolioApi, OrdersApi } from "kalshi-typescript";
|
|
3
|
+
interface UseKalshiResult {
|
|
4
|
+
config: KalshiConfig | null;
|
|
5
|
+
marketApi: MarketApi | null;
|
|
6
|
+
portfolioApi: PortfolioApi | null;
|
|
7
|
+
ordersApi: OrdersApi | null;
|
|
8
|
+
isConfigured: boolean;
|
|
9
|
+
configError: string | null;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Hook to initialize and provide Kalshi API clients
|
|
13
|
+
*/
|
|
14
|
+
export declare function useKalshi(): UseKalshiResult;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=useKalshi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useKalshi.d.ts","sourceRoot":"","sources":["../../src/hooks/useKalshi.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,YAAY,EAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE5E,UAAU,eAAe;IACvB,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAClC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,eAAe,CAuC3C"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { useState, useEffect, useMemo } from "react";
|
|
2
|
+
import { getKalshiConfig, createMarketApi, createPortfolioApi, createOrdersApi, } from "@newyorkcompute/kalshi-core";
|
|
3
|
+
/**
|
|
4
|
+
* Hook to initialize and provide Kalshi API clients
|
|
5
|
+
*/
|
|
6
|
+
export function useKalshi() {
|
|
7
|
+
const [config, setConfig] = useState(null);
|
|
8
|
+
const [configError, setConfigError] = useState(null);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
try {
|
|
11
|
+
const kalshiConfig = getKalshiConfig();
|
|
12
|
+
setConfig(kalshiConfig);
|
|
13
|
+
setConfigError(null);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
setConfigError(error instanceof Error ? error.message : "Unknown configuration error");
|
|
17
|
+
}
|
|
18
|
+
}, []);
|
|
19
|
+
const marketApi = useMemo(() => (config ? createMarketApi(config) : null), [config]);
|
|
20
|
+
const portfolioApi = useMemo(() => (config ? createPortfolioApi(config) : null), [config]);
|
|
21
|
+
const ordersApi = useMemo(() => (config ? createOrdersApi(config) : null), [config]);
|
|
22
|
+
return {
|
|
23
|
+
config,
|
|
24
|
+
marketApi,
|
|
25
|
+
portfolioApi,
|
|
26
|
+
ordersApi,
|
|
27
|
+
isConfigured: config !== null,
|
|
28
|
+
configError,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=useKalshi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useKalshi.js","sourceRoot":"","sources":["../../src/hooks/useKalshi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,EACL,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,eAAe,GAEhB,MAAM,6BAA6B,CAAC;AAYrC;;GAEG;AACH,MAAM,UAAU,SAAS;IACvB,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAsB,IAAI,CAAC,CAAC;IAChE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAEpE,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;YACvC,SAAS,CAAC,YAAY,CAAC,CAAC;YACxB,cAAc,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,cAAc,CACZ,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,6BAA6B,CACvE,CAAC;QACJ,CAAC;IACH,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,SAAS,GAAG,OAAO,CACvB,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAC/C,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,MAAM,YAAY,GAAG,OAAO,CAC1B,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAClD,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,MAAM,SAAS,GAAG,OAAO,CACvB,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAC/C,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,OAAO;QACL,MAAM;QACN,SAAS;QACT,YAAY;QACZ,SAAS;QACT,YAAY,EAAE,MAAM,KAAK,IAAI;QAC7B,WAAW;KACZ,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { MarketDisplay } from "@newyorkcompute/kalshi-core";
|
|
2
|
+
interface UseMarketsResult {
|
|
3
|
+
markets: MarketDisplay[];
|
|
4
|
+
isLoading: boolean;
|
|
5
|
+
error: string | null;
|
|
6
|
+
refresh: () => Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Hook to fetch and poll market data
|
|
10
|
+
*/
|
|
11
|
+
export declare function useMarkets(pollInterval?: number): UseMarketsResult;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=useMarkets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMarkets.d.ts","sourceRoot":"","sources":["../../src/hooks/useMarkets.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAejE,UAAU,gBAAgB;IACxB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,YAAY,SAAQ,GAAG,gBAAgB,CAuEjE"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { useState, useEffect, useCallback, useRef } from "react";
|
|
2
|
+
import { GetMarketsStatusEnum } from "@newyorkcompute/kalshi-core";
|
|
3
|
+
import { useKalshi } from "./useKalshi.js";
|
|
4
|
+
// Helper to check if markets data has changed (compares by ticker list and prices)
|
|
5
|
+
function marketsChanged(prev, next) {
|
|
6
|
+
if (prev.length !== next.length)
|
|
7
|
+
return true;
|
|
8
|
+
for (let i = 0; i < prev.length; i++) {
|
|
9
|
+
if (prev[i].ticker !== next[i].ticker)
|
|
10
|
+
return true;
|
|
11
|
+
if (prev[i].yes_bid !== next[i].yes_bid)
|
|
12
|
+
return true;
|
|
13
|
+
if (prev[i].yes_ask !== next[i].yes_ask)
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Hook to fetch and poll market data
|
|
20
|
+
*/
|
|
21
|
+
export function useMarkets(pollInterval = 30000) {
|
|
22
|
+
const { marketApi } = useKalshi();
|
|
23
|
+
const [markets, setMarkets] = useState([]);
|
|
24
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
25
|
+
const [error, setError] = useState(null);
|
|
26
|
+
const marketsRef = useRef([]);
|
|
27
|
+
const fetchMarkets = useCallback(async () => {
|
|
28
|
+
if (!marketApi)
|
|
29
|
+
return;
|
|
30
|
+
try {
|
|
31
|
+
// API signature: getMarkets(limit, cursor, eventTicker, seriesTicker, minCreatedTs, maxCreatedTs, maxCloseTs, minCloseTs, minSettledTs, maxSettledTs, status, tickers)
|
|
32
|
+
const response = await marketApi.getMarkets(100, // limit
|
|
33
|
+
undefined, // cursor
|
|
34
|
+
undefined, // eventTicker
|
|
35
|
+
undefined, // seriesTicker
|
|
36
|
+
undefined, // minCreatedTs
|
|
37
|
+
undefined, // maxCreatedTs
|
|
38
|
+
undefined, // maxCloseTs
|
|
39
|
+
undefined, // minCloseTs
|
|
40
|
+
undefined, // minSettledTs
|
|
41
|
+
undefined, // maxSettledTs
|
|
42
|
+
GetMarketsStatusEnum.Open // status
|
|
43
|
+
);
|
|
44
|
+
// Map to our display type
|
|
45
|
+
const marketData = (response.data.markets || []).map((m) => ({
|
|
46
|
+
ticker: m.ticker || "",
|
|
47
|
+
title: m.title || "",
|
|
48
|
+
status: (m.status || "open"),
|
|
49
|
+
yes_bid: m.yes_bid,
|
|
50
|
+
yes_ask: m.yes_ask,
|
|
51
|
+
no_bid: m.no_bid,
|
|
52
|
+
no_ask: m.no_ask,
|
|
53
|
+
volume: m.volume,
|
|
54
|
+
open_interest: m.open_interest,
|
|
55
|
+
close_time: m.close_time,
|
|
56
|
+
}));
|
|
57
|
+
// Only update state if data actually changed
|
|
58
|
+
if (marketsChanged(marketsRef.current, marketData)) {
|
|
59
|
+
marketsRef.current = marketData;
|
|
60
|
+
setMarkets(marketData);
|
|
61
|
+
}
|
|
62
|
+
setError(null);
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
setError(err instanceof Error ? err.message : "Failed to fetch markets");
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
setIsLoading(false);
|
|
69
|
+
}
|
|
70
|
+
}, [marketApi]);
|
|
71
|
+
// Initial fetch
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
fetchMarkets();
|
|
74
|
+
}, [fetchMarkets]);
|
|
75
|
+
// Polling
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
if (!marketApi)
|
|
78
|
+
return;
|
|
79
|
+
const interval = setInterval(fetchMarkets, pollInterval);
|
|
80
|
+
return () => clearInterval(interval);
|
|
81
|
+
}, [marketApi, pollInterval, fetchMarkets]);
|
|
82
|
+
return {
|
|
83
|
+
markets,
|
|
84
|
+
isLoading,
|
|
85
|
+
error,
|
|
86
|
+
refresh: fetchMarkets,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=useMarkets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMarkets.js","sourceRoot":"","sources":["../../src/hooks/useMarkets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { OrderbookDisplay } from "@newyorkcompute/kalshi-core";
|
|
2
|
+
interface UseOrderbookResult {
|
|
3
|
+
orderbook: OrderbookDisplay | null;
|
|
4
|
+
isLoading: boolean;
|
|
5
|
+
error: string | null;
|
|
6
|
+
refresh: () => Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Hook to fetch and poll orderbook data for a specific market
|
|
10
|
+
*/
|
|
11
|
+
export declare function useOrderbook(ticker: string | null, pollInterval?: number): UseOrderbookResult;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=useOrderbook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useOrderbook.d.ts","sourceRoot":"","sources":["../../src/hooks/useOrderbook.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAapE,UAAU,kBAAkB;IAC1B,SAAS,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACnC,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,YAAY,SAAQ,GACnB,kBAAkB,CA0EpB"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { useState, useEffect, useCallback, useRef } from "react";
|
|
2
|
+
import { useKalshi } from "./useKalshi.js";
|
|
3
|
+
// Helper to check if orderbook data has changed
|
|
4
|
+
function orderbookChanged(prev, next) {
|
|
5
|
+
if (!prev && !next)
|
|
6
|
+
return false;
|
|
7
|
+
if (!prev || !next)
|
|
8
|
+
return true;
|
|
9
|
+
return JSON.stringify(prev) !== JSON.stringify(next);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Hook to fetch and poll orderbook data for a specific market
|
|
13
|
+
*/
|
|
14
|
+
export function useOrderbook(ticker, pollInterval = 10000) {
|
|
15
|
+
const { marketApi } = useKalshi();
|
|
16
|
+
const [orderbook, setOrderbook] = useState(null);
|
|
17
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
18
|
+
const [error, setError] = useState(null);
|
|
19
|
+
const orderbookRef = useRef(null);
|
|
20
|
+
const fetchOrderbook = useCallback(async () => {
|
|
21
|
+
if (!marketApi || !ticker) {
|
|
22
|
+
if (orderbookRef.current !== null) {
|
|
23
|
+
orderbookRef.current = null;
|
|
24
|
+
setOrderbook(null);
|
|
25
|
+
}
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
// Only show loading on first fetch
|
|
29
|
+
if (!orderbookRef.current) {
|
|
30
|
+
setIsLoading(true);
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
// API signature: getMarketOrderbook(ticker, depth)
|
|
34
|
+
const response = await marketApi.getMarketOrderbook(ticker, 10);
|
|
35
|
+
const ob = response.data.orderbook;
|
|
36
|
+
let newOrderbook = null;
|
|
37
|
+
if (ob) {
|
|
38
|
+
// Orderbook has yes_dollars and no_dollars arrays (string[][])
|
|
39
|
+
// Each entry is [price_string, quantity_string]
|
|
40
|
+
const parseLevel = (entry) => [
|
|
41
|
+
parseFloat(entry[0] || "0"),
|
|
42
|
+
parseInt(entry[1] || "0", 10),
|
|
43
|
+
];
|
|
44
|
+
newOrderbook = {
|
|
45
|
+
yes: (ob.yes_dollars || []).map(parseLevel),
|
|
46
|
+
no: (ob.no_dollars || []).map(parseLevel),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
// Only update state if data actually changed
|
|
50
|
+
if (orderbookChanged(orderbookRef.current, newOrderbook)) {
|
|
51
|
+
orderbookRef.current = newOrderbook;
|
|
52
|
+
setOrderbook(newOrderbook);
|
|
53
|
+
}
|
|
54
|
+
setError(null);
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
setError(err instanceof Error ? err.message : "Failed to fetch orderbook");
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
setIsLoading(false);
|
|
61
|
+
}
|
|
62
|
+
}, [marketApi, ticker]);
|
|
63
|
+
// Fetch when ticker changes
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
fetchOrderbook();
|
|
66
|
+
}, [fetchOrderbook]);
|
|
67
|
+
// Polling
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (!marketApi || !ticker)
|
|
70
|
+
return;
|
|
71
|
+
const interval = setInterval(fetchOrderbook, pollInterval);
|
|
72
|
+
return () => clearInterval(interval);
|
|
73
|
+
}, [marketApi, ticker, pollInterval, fetchOrderbook]);
|
|
74
|
+
return {
|
|
75
|
+
orderbook,
|
|
76
|
+
isLoading,
|
|
77
|
+
error,
|
|
78
|
+
refresh: fetchOrderbook,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=useOrderbook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useOrderbook.js","sourceRoot":"","sources":["../../src/hooks/useOrderbook.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { PositionDisplay } from "@newyorkcompute/kalshi-core";
|
|
2
|
+
interface Balance {
|
|
3
|
+
balance: number;
|
|
4
|
+
portfolioValue: number;
|
|
5
|
+
}
|
|
6
|
+
interface UsePortfolioResult {
|
|
7
|
+
balance: Balance | null;
|
|
8
|
+
positions: PositionDisplay[];
|
|
9
|
+
isLoading: boolean;
|
|
10
|
+
error: string | null;
|
|
11
|
+
refresh: () => Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Hook to fetch and poll portfolio data (balance + positions)
|
|
15
|
+
*/
|
|
16
|
+
export declare function usePortfolio(pollInterval?: number): UsePortfolioResult;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=usePortfolio.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePortfolio.d.ts","sourceRoot":"","sources":["../../src/hooks/usePortfolio.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAcnE,UAAU,OAAO;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,kBAAkB;IAC1B,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,YAAY,SAAQ,GAAG,kBAAkB,CA8ErE"}
|