@openmarketsai/order-sheet 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/LICENSE +201 -0
- package/NOTICE +5 -0
- package/README.md +183 -0
- package/dist/auth.d.ts +24 -0
- package/dist/auth.js +36 -0
- package/dist/auth.js.map +1 -0
- package/dist/client.d.ts +158 -0
- package/dist/client.js +253 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +34 -0
- package/dist/errors.js +34 -0
- package/dist/errors.js.map +1 -0
- package/dist/generated/contract.d.ts +28 -0
- package/dist/generated/contract.js +176 -0
- package/dist/generated/contract.js.map +1 -0
- package/dist/http.d.ts +19 -0
- package/dist/http.js +58 -0
- package/dist/http.js.map +1 -0
- package/dist/index.cjs +1742 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/math.d.ts +22 -0
- package/dist/math.js +55 -0
- package/dist/math.js.map +1 -0
- package/dist/messages.d.ts +21 -0
- package/dist/messages.js +97 -0
- package/dist/messages.js.map +1 -0
- package/dist/odds.d.ts +12 -0
- package/dist/odds.js +33 -0
- package/dist/odds.js.map +1 -0
- package/dist/quote.d.ts +20 -0
- package/dist/quote.js +117 -0
- package/dist/quote.js.map +1 -0
- package/dist/react.cjs +2137 -0
- package/dist/react.d.ts +157 -0
- package/dist/react.js +297 -0
- package/dist/react.js.map +1 -0
- package/dist/sheet.d.ts +77 -0
- package/dist/sheet.js +648 -0
- package/dist/sheet.js.map +1 -0
- package/dist/stream.d.ts +71 -0
- package/dist/stream.js +160 -0
- package/dist/stream.js.map +1 -0
- package/dist/types.d.ts +287 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/styles.css +284 -0
- package/dist/ui/theme.d.ts +108 -0
- package/dist/ui/theme.js +180 -0
- package/dist/ui/theme.js.map +1 -0
- package/dist/ui.cjs +2606 -0
- package/dist/ui.d.ts +124 -0
- package/dist/ui.js +154 -0
- package/dist/ui.js.map +1 -0
- package/dist/validate.d.ts +20 -0
- package/dist/validate.js +126 -0
- package/dist/validate.js.map +1 -0
- package/dist/venues.d.ts +19 -0
- package/dist/venues.js +103 -0
- package/dist/venues.js.map +1 -0
- package/dist/wire.d.ts +382 -0
- package/dist/wire.js +2 -0
- package/dist/wire.js.map +1 -0
- package/package.json +78 -0
package/dist/ui.d.ts
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @openmarketsai/order-sheet/ui — the styled sheet, in the OpenMarkets brand by
|
|
3
|
+
* default, restyled three ways: a `theme` (colours, type, radius, density,
|
|
4
|
+
* scheme), `classNames` per part, and `slots` to replace any part with your own
|
|
5
|
+
* component. Below that sit the unstyled '/react' primitives and the core.
|
|
6
|
+
*
|
|
7
|
+
* import { OrderSheetCard, OrderSheetTheme, createTheme } from '@openmarketsai/order-sheet/ui'
|
|
8
|
+
* import '@openmarketsai/order-sheet/ui/styles.css'
|
|
9
|
+
*
|
|
10
|
+
* <OrderSheetTheme theme={createTheme({ accent: '#c7780f', radius: '10px' })}>
|
|
11
|
+
* <OrderSheetCard client={om} position={{ liquidityHash }} />
|
|
12
|
+
* </OrderSheetTheme>
|
|
13
|
+
*/
|
|
14
|
+
import { type ComponentType, type CSSProperties, type ReactNode } from 'react';
|
|
15
|
+
import type { OrderSheetClient } from './client.js';
|
|
16
|
+
import type { Sheet, SheetInit } from './sheet.js';
|
|
17
|
+
import { OrderSheet, type OrderSheetHandle } from './react.js';
|
|
18
|
+
import type { Issue, PositionRef, VenueOption } from './types.js';
|
|
19
|
+
import type { OddsFormat } from './odds.js';
|
|
20
|
+
import { createTheme, deriveSoft, openmarkets, presets, slate, themeId, themeToCss, type Theme, type ThemeInput, type ThemeScheme, type ThemeTokens } from './ui/theme.js';
|
|
21
|
+
import type { OrderSheetError } from './errors.js';
|
|
22
|
+
export { createTheme, presets, openmarkets, slate, themeToCss, themeId, deriveSoft as deriveSoftTheme };
|
|
23
|
+
export type { Theme, ThemeInput, ThemeScheme, ThemeTokens };
|
|
24
|
+
export * from './react.js';
|
|
25
|
+
export interface OrderSheetThemeProps {
|
|
26
|
+
theme?: Theme;
|
|
27
|
+
/** Force a scheme on this subtree (overrides the theme's). */
|
|
28
|
+
scheme?: ThemeScheme;
|
|
29
|
+
className?: string;
|
|
30
|
+
style?: CSSProperties;
|
|
31
|
+
children: ReactNode;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Renders `<div class="oms-root oms-theme-…" data-oms-theme="…">` with the
|
|
35
|
+
* theme's `--oms-*` variables in an inline `<style>` scoped to that class. The
|
|
36
|
+
* base stylesheet (`styles.css`) already carries the OpenMarkets defaults, so
|
|
37
|
+
* this is only needed to change them.
|
|
38
|
+
*/
|
|
39
|
+
export declare function OrderSheetTheme({ theme, scheme, className, style, children }: OrderSheetThemeProps): import("react/jsx-runtime").JSX.Element;
|
|
40
|
+
export type OrderSheetPart = 'root' | 'header' | 'title' | 'subtitle' | 'venues' | 'venue' | 'venueName' | 'venuePrice' | 'venueReason' | 'mode' | 'orderType' | 'fields' | 'stake' | 'price' | 'quote' | 'issues' | 'issue' | 'hint' | 'submit' | 'outcome' | 'footer';
|
|
41
|
+
export interface PartState {
|
|
42
|
+
handle: OrderSheetHandle;
|
|
43
|
+
venue?: VenueOption;
|
|
44
|
+
issue?: Issue;
|
|
45
|
+
}
|
|
46
|
+
export type ClassNames = Partial<Record<OrderSheetPart, string | ((s: PartState) => string | false | null | undefined)>>;
|
|
47
|
+
export interface SlotProps {
|
|
48
|
+
handle: OrderSheetHandle;
|
|
49
|
+
labels: CardLabels;
|
|
50
|
+
}
|
|
51
|
+
export interface VenueRowSlotProps extends SlotProps {
|
|
52
|
+
venue: VenueOption;
|
|
53
|
+
}
|
|
54
|
+
export interface IssueSlotProps extends SlotProps {
|
|
55
|
+
issue: Issue;
|
|
56
|
+
}
|
|
57
|
+
export interface Slots {
|
|
58
|
+
Header?: ComponentType<SlotProps>;
|
|
59
|
+
VenueRow?: ComponentType<VenueRowSlotProps>;
|
|
60
|
+
Quote?: ComponentType<SlotProps>;
|
|
61
|
+
Issue?: ComponentType<IssueSlotProps>;
|
|
62
|
+
Submit?: ComponentType<SlotProps>;
|
|
63
|
+
Outcome?: ComponentType<SlotProps>;
|
|
64
|
+
Footer?: ComponentType<SlotProps>;
|
|
65
|
+
}
|
|
66
|
+
export interface CardLabels {
|
|
67
|
+
practice: string;
|
|
68
|
+
real: string;
|
|
69
|
+
market: string;
|
|
70
|
+
limit: string;
|
|
71
|
+
stake: string;
|
|
72
|
+
contracts: string;
|
|
73
|
+
limitPrice: string;
|
|
74
|
+
maxPrice: string;
|
|
75
|
+
venue: string;
|
|
76
|
+
price: string;
|
|
77
|
+
cost: string;
|
|
78
|
+
toWin: string;
|
|
79
|
+
fee: string;
|
|
80
|
+
profit: string;
|
|
81
|
+
leftover: string;
|
|
82
|
+
best: string;
|
|
83
|
+
connected: string;
|
|
84
|
+
notConnected: string;
|
|
85
|
+
testMode: string;
|
|
86
|
+
auto: string;
|
|
87
|
+
cancelOrder: string;
|
|
88
|
+
newOrder: string;
|
|
89
|
+
editOrder: string;
|
|
90
|
+
placing: string;
|
|
91
|
+
loading: string;
|
|
92
|
+
substituted: string;
|
|
93
|
+
fixes: Partial<Record<Issue['fix'], string>>;
|
|
94
|
+
phases: Partial<Record<OrderSheetHandle['phase'], string>>;
|
|
95
|
+
}
|
|
96
|
+
export declare const DEFAULT_LABELS: CardLabels;
|
|
97
|
+
export interface OrderSheetCardProps {
|
|
98
|
+
/** Omit when wrapped in <OrderSheetProvider>. */
|
|
99
|
+
client?: OrderSheetClient | null;
|
|
100
|
+
/** The position to open a sheet for — or a Sheet you opened yourself (yours to destroy). */
|
|
101
|
+
position: PositionRef | Sheet;
|
|
102
|
+
init?: SheetInit;
|
|
103
|
+
theme?: Theme;
|
|
104
|
+
scheme?: ThemeScheme;
|
|
105
|
+
classNames?: ClassNames;
|
|
106
|
+
slots?: Slots;
|
|
107
|
+
labels?: Partial<CardLabels>;
|
|
108
|
+
oddsFormat?: OddsFormat;
|
|
109
|
+
/** Show venues the current mode cannot use, blocked with the reason (default true — the user should see where the better price is). */
|
|
110
|
+
showBlockedVenues?: boolean;
|
|
111
|
+
/** Show the practice / real switch (default: when the account has both modes). */
|
|
112
|
+
showModeSwitch?: boolean;
|
|
113
|
+
showOrderType?: boolean;
|
|
114
|
+
showFees?: boolean;
|
|
115
|
+
title?: ReactNode;
|
|
116
|
+
subtitle?: ReactNode;
|
|
117
|
+
onOutcome?: Parameters<typeof OrderSheet.Root>[0]['onOutcome'];
|
|
118
|
+
onPlaceError?: (e: OrderSheetError) => void;
|
|
119
|
+
/** Called when the user wants to fix something the sheet cannot (connect a venue, fund it, upgrade). */
|
|
120
|
+
onFix?: (fix: Issue['fix'], issue: Issue, handle: OrderSheetHandle) => void;
|
|
121
|
+
className?: string;
|
|
122
|
+
style?: CSSProperties;
|
|
123
|
+
}
|
|
124
|
+
export declare function OrderSheetCard(props: OrderSheetCardProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/ui.js
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* @openmarketsai/order-sheet/ui — the styled sheet, in the OpenMarkets brand by
|
|
4
|
+
* default, restyled three ways: a `theme` (colours, type, radius, density,
|
|
5
|
+
* scheme), `classNames` per part, and `slots` to replace any part with your own
|
|
6
|
+
* component. Below that sit the unstyled '/react' primitives and the core.
|
|
7
|
+
*
|
|
8
|
+
* import { OrderSheetCard, OrderSheetTheme, createTheme } from '@openmarketsai/order-sheet/ui'
|
|
9
|
+
* import '@openmarketsai/order-sheet/ui/styles.css'
|
|
10
|
+
*
|
|
11
|
+
* <OrderSheetTheme theme={createTheme({ accent: '#c7780f', radius: '10px' })}>
|
|
12
|
+
* <OrderSheetCard client={om} position={{ liquidityHash }} />
|
|
13
|
+
* </OrderSheetTheme>
|
|
14
|
+
*/
|
|
15
|
+
import { useId, useMemo } from 'react';
|
|
16
|
+
import { OrderSheet, useOrderSheet } from './react.js';
|
|
17
|
+
import { createTheme, deriveSoft, openmarkets, presets, slate, themeId, themeToCss } from './ui/theme.js';
|
|
18
|
+
export { createTheme, presets, openmarkets, slate, themeToCss, themeId, deriveSoft as deriveSoftTheme };
|
|
19
|
+
export * from './react.js';
|
|
20
|
+
/**
|
|
21
|
+
* Renders `<div class="oms-root oms-theme-…" data-oms-theme="…">` with the
|
|
22
|
+
* theme's `--oms-*` variables in an inline `<style>` scoped to that class. The
|
|
23
|
+
* base stylesheet (`styles.css`) already carries the OpenMarkets defaults, so
|
|
24
|
+
* this is only needed to change them.
|
|
25
|
+
*/
|
|
26
|
+
export function OrderSheetTheme({ theme, scheme, className, style, children }) {
|
|
27
|
+
const t = theme ?? openmarkets;
|
|
28
|
+
const id = useMemo(() => themeId(t), [t]);
|
|
29
|
+
const css = useMemo(() => (theme ? themeToCss(t, `.oms-theme-${id}`) : ''), [theme, t, id]);
|
|
30
|
+
const effectiveScheme = scheme ?? t.scheme;
|
|
31
|
+
return (_jsxs("div", { className: cx('oms-root', theme && `oms-theme-${id}`, className), "data-oms-theme": effectiveScheme === 'system' ? undefined : effectiveScheme, style: style, children: [css && _jsx("style", { "data-oms-theme-id": id, dangerouslySetInnerHTML: { __html: css } }), children] }));
|
|
32
|
+
}
|
|
33
|
+
export const DEFAULT_LABELS = {
|
|
34
|
+
practice: 'Practice',
|
|
35
|
+
real: 'Real money',
|
|
36
|
+
market: 'Market',
|
|
37
|
+
limit: 'Limit',
|
|
38
|
+
stake: 'Stake',
|
|
39
|
+
contracts: 'Contracts',
|
|
40
|
+
limitPrice: 'Limit price',
|
|
41
|
+
maxPrice: 'Max price',
|
|
42
|
+
venue: 'Venue',
|
|
43
|
+
price: 'Price',
|
|
44
|
+
cost: 'Cost',
|
|
45
|
+
toWin: 'To win',
|
|
46
|
+
fee: 'Fee',
|
|
47
|
+
profit: 'Profit',
|
|
48
|
+
leftover: 'left over',
|
|
49
|
+
best: 'best',
|
|
50
|
+
connected: 'connected',
|
|
51
|
+
notConnected: 'not connected',
|
|
52
|
+
testMode: 'test',
|
|
53
|
+
auto: 'auto',
|
|
54
|
+
cancelOrder: 'Cancel order',
|
|
55
|
+
newOrder: 'New order',
|
|
56
|
+
editOrder: 'Edit order',
|
|
57
|
+
placing: 'Placing…',
|
|
58
|
+
loading: 'Loading venues…',
|
|
59
|
+
substituted: 'Filled on a different venue than requested — report this.',
|
|
60
|
+
fixes: {
|
|
61
|
+
raise_stake: 'Raise stake', lower_stake: 'Lower stake', round_stake: 'Round', raise_price: 'Raise price', lower_price: 'Lower price',
|
|
62
|
+
connect_venue: 'Connect', fund_venue: 'Add funds', switch_venue: 'Switch venue', switch_to_paper: 'Use practice', switch_to_real: 'Use real money',
|
|
63
|
+
use_market: 'Use market', use_limit: 'Use limit', grant_scope: 'Allow trading', upgrade_plan: 'Upgrade', retry: 'Retry',
|
|
64
|
+
},
|
|
65
|
+
phases: {
|
|
66
|
+
filled: 'Filled', partial: 'Partly filled', resting: 'Resting on the book', pending: 'Pending at the venue', failed: 'Not placed',
|
|
67
|
+
cancelled: 'Cancelled', settled: 'Settled',
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
function cx(...parts) {
|
|
71
|
+
const out = parts.filter(Boolean).join(' ');
|
|
72
|
+
return out || undefined;
|
|
73
|
+
}
|
|
74
|
+
export function OrderSheetCard(props) {
|
|
75
|
+
const h = useOrderSheet(props.client ?? null, props.position, { oddsFormat: props.oddsFormat, ...(props.init ?? {}) });
|
|
76
|
+
const uid = useId();
|
|
77
|
+
const ids = { venues: `${uid}-venues`, stake: `${uid}-stake`, stakeHint: `${uid}-stake-hint`, price: `${uid}-price` };
|
|
78
|
+
const labels = useMemo(() => ({ ...DEFAULT_LABELS, ...(props.labels ?? {}), fixes: { ...DEFAULT_LABELS.fixes, ...(props.labels?.fixes ?? {}) }, phases: { ...DEFAULT_LABELS.phases, ...(props.labels?.phases ?? {}) } }), [props.labels]);
|
|
79
|
+
const cn = (part, base, s = {}) => {
|
|
80
|
+
const v = props.classNames?.[part];
|
|
81
|
+
return cx(base, typeof v === 'function' ? v({ handle: h, ...s }) : v);
|
|
82
|
+
};
|
|
83
|
+
const S = props.slots ?? {};
|
|
84
|
+
const showMode = props.showModeSwitch ?? ((h.account?.moneyModes.length ?? 0) > 1);
|
|
85
|
+
const showOrderType = props.showOrderType ?? ((h.venue?.supports.orderTypes.length ?? 1) > 1 && h.mode === 'real');
|
|
86
|
+
const placed = !!h.result && ['filled', 'partial', 'resting', 'pending', 'failed', 'cancelled', 'settled'].includes(h.phase);
|
|
87
|
+
const testMode = h.account?.environment === 'test';
|
|
88
|
+
const card = (_jsxs(OrderSheet.Root, { handle: h, className: cn('root', 'oms-sheet', {}), onOutcome: props.onOutcome, onPlaceError: props.onPlaceError, style: props.style, "aria-busy": h.loading || h.phase === 'placing' || undefined, children: [S.Header ? _jsx(S.Header, { handle: h, labels: labels }) : (_jsxs("header", { className: cn('header', 'oms-header'), children: [_jsx("h2", { className: cn('title', 'oms-title'), children: props.title ?? h.position?.title ?? ' ' }), _jsxs("p", { className: cn('subtitle', 'oms-subtitle'), children: [props.subtitle ?? h.position?.market_label ?? '', testMode && _jsxs(_Fragment, { children: [" \u00B7 ", _jsx("span", { className: "oms-chip oms-chip--test", children: labels.testMode })] })] })] })), h.loading && !h.position && _jsx("p", { className: "oms-skeleton", "aria-live": "polite", children: labels.loading }), showMode && !placed && (_jsx(OrderSheet.Mode, { className: cn('mode', 'oms-segmented'), labels: { paper: labels.practice, real: labels.real } })), !placed && (_jsxs("div", { children: [_jsx("span", { className: "oms-label", id: ids.venues, children: labels.venue }), _jsx(OrderSheet.Venues, { className: cn('venues', 'oms-venues'), hideBlocked: props.showBlockedVenues === false, "aria-labelledby": ids.venues, render: (v) => S.VenueRow ? _jsx(S.VenueRow, { handle: h, venue: v, labels: labels }) : (_jsxs(_Fragment, { children: [v.logoUrl ? _jsx("img", { className: "oms-venue-logo", src: v.logoUrl, alt: "" }) : _jsx("span", { className: "oms-venue-logo oms-venue-logo--placeholder", "aria-hidden": "true" }), _jsxs("span", { className: "oms-venue-main", children: [_jsxs("span", { className: cn('venueName', 'oms-venue-name', { venue: v }), children: [v.name, v.best && _jsx("span", { className: "oms-chip oms-chip--best", children: labels.best }), h.mode === 'real' && v.account.connected && _jsx("span", { className: "oms-chip oms-chip--connected", children: labels.connected }), h.mode === 'real' && !v.account.connected && v.constraints?.connectable && _jsx("span", { className: "oms-chip oms-chip--off", children: labels.notConnected })] }), v.eligibility.issues[0] && _jsx("span", { className: cn('venueReason', 'oms-venue-reason', { venue: v }), children: v.eligibility.issues[0].message })] }), _jsx("span", { className: cn('venuePrice', 'oms-venue-price', { venue: v }), children: v.display.price })] })) }), _jsx(OrderSheet.Hint, { className: cn('hint', 'oms-hint'), render: (v) => (_jsx("button", { type: "button", className: "oms-link", onClick: () => h.select(v.partnerId), children: h.hint?.message })) })] })), showOrderType && !placed && (_jsx(OrderSheet.OrderType, { className: cn('orderType', 'oms-segmented') })), !placed && (_jsxs("div", { className: cn('fields', 'oms-fields'), children: [_jsxs("div", { className: cn('stake', 'oms-field'), children: [_jsx("label", { className: "oms-label", htmlFor: ids.stake, children: h.stake.unit === 'amount' ? labels.stake : labels.contracts }), _jsxs("div", { className: "oms-input-row", children: [_jsx(OrderSheet.Stake, { id: ids.stake, className: "oms-input", bare: true, "aria-describedby": ids.stakeHint }), _jsxs("div", { className: "oms-input-unit", role: "group", "aria-label": "Stake unit", children: [_jsx("button", { type: "button", className: "oms-segment", "data-unit": "amount", "aria-pressed": h.stake.unit === 'amount', onClick: () => h.setStake(h.stake.value, 'amount'), children: h.quote?.currency && h.quote.currency !== 'USD' ? h.quote.currency : '$' }), _jsx("button", { type: "button", className: "oms-segment", "data-unit": "shares", "aria-pressed": h.stake.unit === 'shares', onClick: () => h.setStake(h.stake.value, 'shares'), children: "#" })] })] }), _jsx("span", { id: ids.stakeHint, className: "oms-input-hint", children: stakeHint(h) })] }), _jsxs("div", { className: cn('price', 'oms-field'), "data-order-type": h.orderType, children: [_jsx("label", { className: "oms-label", htmlFor: ids.price, children: h.orderType === 'limit' ? labels.limitPrice : labels.maxPrice }), _jsx("div", { className: "oms-input-row", children: _jsx(OrderSheet.Price, { id: ids.price, className: "oms-input", bare: true }) }), _jsx("span", { className: "oms-input-hint", children: h.maxPriceIsAuto ? _jsxs(_Fragment, { children: [labels.auto, h.orderType === 'market' && h.venue?.price != null ? ` · quote + ${Math.round(h.slippage * 100)}¢` : ''] }) : _jsx("button", { type: "button", className: "oms-link", onClick: () => h.setMaxPrice(null), children: labels.auto }) })] })] })), !placed && (S.Quote ? _jsx(S.Quote, { handle: h, labels: labels }) : (_jsx(OrderSheet.Quote, { className: cn('quote', 'oms-quote'), render: () => h.quote ? (_jsxs(_Fragment, { children: [_jsxs("dl", { className: "oms-quote-row", children: [_jsx("dt", { children: labels.price }), _jsxs("dd", { children: [h.quote.display.price, h.quote.wouldRest ? ' · rests' : ''] })] }), _jsxs("dl", { className: "oms-quote-row", children: [_jsx("dt", { children: labels.contracts }), _jsxs("dd", { children: [h.quote.contracts, h.quote.leftover > 0 ? ` · ${h.quote.display.cost} (${fmtLeftover(h)} ${labels.leftover})` : ''] })] }), (props.showFees ?? true) && h.quote.fee && h.quote.mode === 'real' && _jsxs("dl", { className: "oms-quote-row", children: [_jsx("dt", { children: labels.fee }), _jsx("dd", { children: h.quote.display.fee })] }), _jsxs("dl", { className: "oms-quote-row oms-quote-row--total", children: [_jsx("dt", { children: labels.cost }), _jsx("dd", { children: h.quote.display.cost })] }), _jsxs("dl", { className: "oms-quote-row", children: [_jsx("dt", { children: labels.toWin }), _jsx("dd", { children: h.quote.display.payout })] }), _jsxs("dl", { className: "oms-quote-row oms-quote-row--profit", children: [_jsx("dt", { children: labels.profit }), _jsx("dd", { children: h.quote.display.profit })] }), h.quote.freshness === 'stale' && _jsx("p", { className: "oms-quote-note", children: "Price may have moved \u2014 the venue confirms on placement." })] })) : null }))), _jsx(OrderSheet.Issues, { className: cn('issues', 'oms-issues'), severities: placed ? [] : undefined, render: (i) => S.Issue ? _jsx(S.Issue, { handle: h, issue: i, labels: labels }) : (_jsxs(_Fragment, { children: [_jsx("span", { className: cn('issue', '', { issue: i }), children: i.message }), i.fix !== 'none' && (_jsx("button", { type: "button", className: "oms-issue-fix", onClick: () => applyFix(i, h, props.onFix), children: labels.fixes[i.fix] ?? i.fix }))] })) }), !placed && (S.Submit ? _jsx(S.Submit, { handle: h, labels: labels }) : (_jsxs("div", { className: "oms-submit-row", children: [_jsx(OrderSheet.Submit, { className: cn('submit', 'oms-submit') }), h.phase === 'confirming' && _jsx("button", { type: "button", className: "oms-submit-secondary", onClick: h.cancelConfirm, children: labels.editOrder })] }))), placed && (S.Outcome ? _jsx(S.Outcome, { handle: h, labels: labels }) : (_jsx(OrderSheet.Outcome, { className: cn('outcome', 'oms-outcome'), render: () => {
|
|
89
|
+
const leg = h.result?.legs[0];
|
|
90
|
+
return (_jsxs(_Fragment, { children: [_jsx("p", { className: "oms-outcome-title", children: labels.phases[h.phase] ?? h.phase }), leg?.issue && _jsx("p", { className: "oms-outcome-detail", children: leg.issue.message }), leg && leg.fill.shares > 0 && _jsxs("p", { className: "oms-outcome-detail", children: [leg.fill.shares, " ", labels.contracts.toLowerCase(), " @ ", leg.fill.avgPrice != null ? `${Math.round(leg.fill.avgPrice * 100)}¢` : '—', leg.fill.unfilled > 0 ? ` · ${fmtMoney(leg.fill.unfilled, h.quote?.currency ?? 'USD')} ${labels.leftover}` : ''] }), h.orders.some((o) => o.settled) && _jsx("p", { className: "oms-outcome-detail", children: h.orders.map((o) => o.settled ? `${o.settled.result}: ${fmtMoney(o.settled.netWinnings, h.quote?.currency ?? 'USD')}` : '').join(' ') }), leg?.substituted && _jsx("p", { className: "oms-outcome-detail", children: labels.substituted }), leg && leg.routerOrderIds.length > 0 && _jsx("p", { className: "oms-outcome-ids", children: leg.routerOrderIds.join(', ') }), _jsxs("div", { className: "oms-outcome-actions", children: [(h.phase === 'resting' || h.phase === 'pending' || h.phase === 'partial') && h.venue?.supports.cancel && _jsx("button", { type: "button", className: "oms-button", onClick: () => void h.cancel(), children: labels.cancelOrder }), _jsx("button", { type: "button", className: "oms-button", onClick: h.reset, children: labels.newOrder })] })] }));
|
|
91
|
+
} }))), S.Footer ? _jsx(S.Footer, { handle: h, labels: labels }) : (_jsxs("footer", { className: cn('footer', 'oms-footer'), children: [_jsxs("span", { children: [h.mode === 'paper' ? labels.practice : labels.real, h.venue ? ` · ${h.venue.name}` : ''] }), h.preflightStatus === 'pending' && _jsx("span", { "aria-live": "polite", children: "checking\u2026" })] }))] }));
|
|
92
|
+
return props.theme || props.scheme || props.className ? (_jsx(OrderSheetTheme, { theme: props.theme, scheme: props.scheme, className: props.className, children: card })) : (_jsx("div", { className: "oms-root", children: card }));
|
|
93
|
+
}
|
|
94
|
+
function stakeHint(h) {
|
|
95
|
+
const c = h.venue?.constraints;
|
|
96
|
+
if (!c || h.mode !== 'real')
|
|
97
|
+
return '';
|
|
98
|
+
const parts = [];
|
|
99
|
+
if (c.size.min_usd > 0)
|
|
100
|
+
parts.push(`min $${c.size.min_usd}`);
|
|
101
|
+
if (c.size.max_usd != null)
|
|
102
|
+
parts.push(`max $${c.size.max_usd}`);
|
|
103
|
+
if (c.size.whole_contracts)
|
|
104
|
+
parts.push(c.size.min_contracts > 1 ? `≥ ${c.size.min_contracts} contracts` : 'whole contracts');
|
|
105
|
+
return parts.join(' · ');
|
|
106
|
+
}
|
|
107
|
+
function fmtLeftover(h) {
|
|
108
|
+
return h.quote ? fmtMoney(h.quote.leftover, h.quote.currency) : '';
|
|
109
|
+
}
|
|
110
|
+
function fmtMoney(n, currency) {
|
|
111
|
+
const body = Math.abs(n).toFixed(2);
|
|
112
|
+
return currency === 'USD' ? `$${body}` : `${body} ${currency}`;
|
|
113
|
+
}
|
|
114
|
+
/** The fixes the sheet can apply itself; the rest go to the host through onFix. */
|
|
115
|
+
function applyFix(issue, h, onFix) {
|
|
116
|
+
switch (issue.fix) {
|
|
117
|
+
case 'switch_to_paper':
|
|
118
|
+
h.setMode('paper');
|
|
119
|
+
return;
|
|
120
|
+
case 'switch_to_real':
|
|
121
|
+
h.setMode('real');
|
|
122
|
+
return;
|
|
123
|
+
case 'use_market':
|
|
124
|
+
h.setOrderType('market');
|
|
125
|
+
return;
|
|
126
|
+
case 'use_limit':
|
|
127
|
+
h.setOrderType('limit');
|
|
128
|
+
return;
|
|
129
|
+
case 'switch_venue': {
|
|
130
|
+
const best = h.venues.find((v) => v.best && v.eligibility.status !== 'blocked');
|
|
131
|
+
if (best)
|
|
132
|
+
h.select(best.partnerId);
|
|
133
|
+
else
|
|
134
|
+
onFix?.(issue.fix, issue, h);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
case 'round_stake': {
|
|
138
|
+
const q = h.quote;
|
|
139
|
+
if (q)
|
|
140
|
+
h.setStake(q.cost);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
case 'raise_price': {
|
|
144
|
+
if (h.venue?.price != null)
|
|
145
|
+
h.setMaxPrice(null);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
case 'retry':
|
|
149
|
+
void h.runPreflight();
|
|
150
|
+
return;
|
|
151
|
+
default: onFix?.(issue.fix, issue, h);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=ui.js.map
|
package/dist/ui.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../src/ui.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AccountFacts, MoneyMode, OrderType, StakeUnit, Validation, VenueOption } from './types.js';
|
|
2
|
+
export interface ValidateInput {
|
|
3
|
+
account: AccountFacts | null;
|
|
4
|
+
venue: VenueOption | null;
|
|
5
|
+
venues: VenueOption[];
|
|
6
|
+
mode: MoneyMode;
|
|
7
|
+
orderType: OrderType;
|
|
8
|
+
stake: {
|
|
9
|
+
unit: StakeUnit;
|
|
10
|
+
value: number | null;
|
|
11
|
+
};
|
|
12
|
+
maxPrice: number | null;
|
|
13
|
+
realMoneyEnabled: boolean;
|
|
14
|
+
paperBettable: boolean | null;
|
|
15
|
+
quoteAgeMs: number | null;
|
|
16
|
+
staleAfterMs: number;
|
|
17
|
+
constraintsStale: boolean;
|
|
18
|
+
currency: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function validateSheet(input: ValidateInput): Validation;
|
package/dist/validate.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local validation — instant feedback on every keystroke, evaluated ONLY against
|
|
3
|
+
* the constraints the server served. No venue name and no number lives here.
|
|
4
|
+
* The server remains the authority: a preflight or buy answer supersedes any
|
|
5
|
+
* local verdict, and a `constraints_version` mismatch marks local results stale.
|
|
6
|
+
*/
|
|
7
|
+
import { AMOUNT_TOL, contractsFromAmount, isOnGrid, snapPrice } from './math.js';
|
|
8
|
+
import { localIssue } from './messages.js';
|
|
9
|
+
export function validateSheet(input) {
|
|
10
|
+
const issues = [];
|
|
11
|
+
const { venue, mode, orderType, stake, account } = input;
|
|
12
|
+
const cur = input.currency;
|
|
13
|
+
const push = (i) => { if (!issues.some((x) => x.code === i.code && x.scope === i.scope))
|
|
14
|
+
issues.push(i); };
|
|
15
|
+
// ── account / mode ──
|
|
16
|
+
if (account) {
|
|
17
|
+
if (!account.moneyModes.includes(mode)) {
|
|
18
|
+
// Prefer the server's own reason (real_money_not_permitted, test_mode…),
|
|
19
|
+
// fall back to a generic mode_unavailable.
|
|
20
|
+
const reason = account.issues.find((i) => (mode === 'paper' ? i.code === 'practice_not_permitted' : i.code !== 'practice_not_permitted'));
|
|
21
|
+
push(reason ?? localIssue('mode_unavailable', { detail: mode }));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (mode === 'real' && !input.realMoneyEnabled)
|
|
25
|
+
push(localIssue('real_money_disabled'));
|
|
26
|
+
if (mode === 'paper' && orderType === 'limit')
|
|
27
|
+
push(localIssue('paper_limit_unsupported'));
|
|
28
|
+
if (mode === 'paper' && input.paperBettable === false)
|
|
29
|
+
push(localIssue('not_paper_bettable'));
|
|
30
|
+
if (input.constraintsStale)
|
|
31
|
+
push(localIssue('constraints_stale'));
|
|
32
|
+
// ── venue ──
|
|
33
|
+
if (!venue) {
|
|
34
|
+
push(localIssue('no_venue'));
|
|
35
|
+
return finish(issues);
|
|
36
|
+
}
|
|
37
|
+
for (const i of venue.eligibility.issues)
|
|
38
|
+
push(i);
|
|
39
|
+
const c = venue.constraints;
|
|
40
|
+
const price = orderType === 'limit' ? input.maxPrice : venue.price;
|
|
41
|
+
if (price == null) {
|
|
42
|
+
// no_quote is already among the venue issues for a market order; a limit
|
|
43
|
+
// with no price set cannot be sized either.
|
|
44
|
+
if (orderType === 'limit')
|
|
45
|
+
push(localIssue('no_stake', {}, { fix: 'raise_price' }));
|
|
46
|
+
}
|
|
47
|
+
// ── stake ──
|
|
48
|
+
if (stake.value == null || !(stake.value > 0)) {
|
|
49
|
+
push(localIssue('no_stake'));
|
|
50
|
+
return finish(issues);
|
|
51
|
+
}
|
|
52
|
+
if (price == null)
|
|
53
|
+
return finish(issues);
|
|
54
|
+
const notional = stake.unit === 'amount' ? stake.value : stake.value * price;
|
|
55
|
+
const vctx = { venue: venue.name, currency: cur };
|
|
56
|
+
if (c && mode === 'real') {
|
|
57
|
+
const size = c.size;
|
|
58
|
+
const isFullTake = venue.available != null && Math.abs(notional - venue.available) <= AMOUNT_TOL;
|
|
59
|
+
if (notional + AMOUNT_TOL < size.min_usd && !(size.full_fill_bypasses_min && isFullTake)) {
|
|
60
|
+
push(localIssue('below_min_order', { ...vctx, amount: notional, min: size.min_usd }));
|
|
61
|
+
}
|
|
62
|
+
if (size.max_usd != null && notional - AMOUNT_TOL > size.max_usd) {
|
|
63
|
+
push(localIssue('above_max_order', { ...vctx, amount: notional, max: size.max_usd }));
|
|
64
|
+
}
|
|
65
|
+
if (size.whole_contracts) {
|
|
66
|
+
const contracts = stake.unit === 'shares' ? Math.floor(stake.value + 1e-9) : contractsFromAmount(notional, price);
|
|
67
|
+
const minC = Math.max(1, size.min_contracts);
|
|
68
|
+
if (contracts < minC) {
|
|
69
|
+
push(contracts === 0 && minC === 1
|
|
70
|
+
? localIssue('unfillable', { ...vctx, amount: notional, price })
|
|
71
|
+
: localIssue('below_min_contracts', { ...vctx, amount: notional, price, contracts, min_contracts: minC }));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else if (size.increment_usd && stake.unit === 'amount' && !isOnGrid(notional, size.increment_usd)) {
|
|
75
|
+
push(localIssue('amount_off_increment', { ...vctx, amount: notional, increment: size.increment_usd }));
|
|
76
|
+
}
|
|
77
|
+
// ── price ──
|
|
78
|
+
const pc = c.price;
|
|
79
|
+
if (input.maxPrice != null) {
|
|
80
|
+
if (input.maxPrice + 1e-9 < pc.min || input.maxPrice - 1e-9 > pc.max) {
|
|
81
|
+
push(localIssue('price_out_of_band', { ...vctx, price: input.maxPrice, min: pc.min, max: pc.max }));
|
|
82
|
+
}
|
|
83
|
+
else if (pc.tick && Math.abs(snapPrice(input.maxPrice, pc.tick, pc.min, pc.max) - input.maxPrice) > 1e-6) {
|
|
84
|
+
push(localIssue('price_off_tick', { ...vctx, price: snapPrice(input.maxPrice, pc.tick, pc.min, pc.max), tick: pc.tick }));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (orderType === 'market' && input.maxPrice != null && venue.price != null && venue.price > input.maxPrice + 1e-9) {
|
|
88
|
+
push(localIssue('above_max_price', { ...vctx, price: venue.price, max_price: input.maxPrice }));
|
|
89
|
+
}
|
|
90
|
+
// ── book ──
|
|
91
|
+
if (orderType === 'market' && venue.available != null && notional - AMOUNT_TOL > venue.available) {
|
|
92
|
+
push(localIssue('insufficient_size', { ...vctx, available: venue.available, price: venue.price ?? price }));
|
|
93
|
+
}
|
|
94
|
+
// ── balance (fresh, known) ── a WARNING, as on the server: /buy (without
|
|
95
|
+
// check_all_first, which the sheet does not send) dispatches the leg and the
|
|
96
|
+
// venue decides; an expected balance can lag a deposit.
|
|
97
|
+
const bal = venue.account.expectedBalance;
|
|
98
|
+
if (bal != null && !venue.account.stale && notional - AMOUNT_TOL > bal) {
|
|
99
|
+
push(localIssue('insufficient_balance', { ...vctx, required: notional, balance: bal }, { severity: 'warn' }));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (mode === 'paper' && account?.practiceWallet.balance != null && notional - AMOUNT_TOL > account.practiceWallet.balance) {
|
|
103
|
+
push(localIssue('insufficient_balance', {
|
|
104
|
+
venue: 'your practice wallet', currency: account.practiceWallet.currency, required: notional, balance: account.practiceWallet.balance,
|
|
105
|
+
}, { fix: 'lower_stake' }));
|
|
106
|
+
}
|
|
107
|
+
if (orderType === 'market' && input.maxPrice != null && venue.price != null && venue.price > input.maxPrice + 1e-9 && mode === 'paper') {
|
|
108
|
+
push(localIssue('above_max_price', { ...vctx, price: venue.price, max_price: input.maxPrice }));
|
|
109
|
+
}
|
|
110
|
+
// ── freshness + the better-price hint ──
|
|
111
|
+
if (input.quoteAgeMs != null && input.quoteAgeMs > input.staleAfterMs) {
|
|
112
|
+
push(localIssue('stale_quote', { ...vctx, detail: `${Math.round(input.quoteAgeMs / 1000)}s` }));
|
|
113
|
+
}
|
|
114
|
+
const best = input.venues.find((v) => v.best);
|
|
115
|
+
if (best && best.partnerId !== venue.partnerId && best.price != null && venue.price != null && best.price < venue.price - 1e-9 && orderType === 'market') {
|
|
116
|
+
push(localIssue('better_price_available', { venue: best.name, price: best.price }));
|
|
117
|
+
}
|
|
118
|
+
return finish(issues);
|
|
119
|
+
}
|
|
120
|
+
function finish(issues) {
|
|
121
|
+
const blocking = issues.filter((i) => i.severity === 'block');
|
|
122
|
+
const warnings = issues.filter((i) => i.severity === 'warn');
|
|
123
|
+
const info = issues.filter((i) => i.severity === 'info');
|
|
124
|
+
return { ok: blocking.length === 0, blocking, warnings, info, all: issues };
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"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"}
|
package/dist/venues.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The venue list for a position: every venue quoting it, joined with the
|
|
3
|
+
* account's constraints for it. Pure. Sorted cheapest-first and badged `best`
|
|
4
|
+
* for DISPLAY — the user picks the venue; the sheet never picks for them.
|
|
5
|
+
*/
|
|
6
|
+
import { type OddsFormat } from './odds.js';
|
|
7
|
+
import type { AccountFacts, Issue, MoneyMode, OrderType, VenueOption } from './types.js';
|
|
8
|
+
import type { OrderConstraints, OrderIssue, Position } from './wire.js';
|
|
9
|
+
export declare function fromServerIssue(i: OrderIssue): Issue;
|
|
10
|
+
export interface BuildVenuesInput {
|
|
11
|
+
position: Position;
|
|
12
|
+
constraints: OrderConstraints | null;
|
|
13
|
+
account: AccountFacts | null;
|
|
14
|
+
mode: MoneyMode;
|
|
15
|
+
orderType: OrderType;
|
|
16
|
+
selectedPartnerId: string | null;
|
|
17
|
+
oddsFormat: OddsFormat;
|
|
18
|
+
}
|
|
19
|
+
export declare function buildVenueOptions(input: BuildVenuesInput): VenueOption[];
|
package/dist/venues.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The venue list for a position: every venue quoting it, joined with the
|
|
3
|
+
* account's constraints for it. Pure. Sorted cheapest-first and badged `best`
|
|
4
|
+
* for DISPLAY — the user picks the venue; the sheet never picks for them.
|
|
5
|
+
*/
|
|
6
|
+
import { formatPrice } from './odds.js';
|
|
7
|
+
import { localIssue } from './messages.js';
|
|
8
|
+
export function fromServerIssue(i) {
|
|
9
|
+
return { ...i, source: 'server' };
|
|
10
|
+
}
|
|
11
|
+
export function buildVenueOptions(input) {
|
|
12
|
+
const byId = new Map();
|
|
13
|
+
for (const v of input.constraints?.venues ?? [])
|
|
14
|
+
byId.set(v.partner_id, v);
|
|
15
|
+
const rows = input.position.partner_liquidities;
|
|
16
|
+
// Practice orders fill on the internal book — it is not a venue to pick from.
|
|
17
|
+
const practiceBook = input.account?.practiceWallet.partnerId ?? input.constraints?.account.practice_wallet.partner_id ?? null;
|
|
18
|
+
const options = [];
|
|
19
|
+
for (const row of rows) {
|
|
20
|
+
if (practiceBook && row.partner_id === practiceBook)
|
|
21
|
+
continue;
|
|
22
|
+
const c = byId.get(row.partner_id) ?? null;
|
|
23
|
+
options.push(toOption(row, c, input));
|
|
24
|
+
}
|
|
25
|
+
// Cheapest actionable price wins the badge; ties keep first-listed.
|
|
26
|
+
let best = null;
|
|
27
|
+
for (const o of options) {
|
|
28
|
+
if (!o.actionable || o.price == null)
|
|
29
|
+
continue;
|
|
30
|
+
if (!best || o.price < (best.price ?? Infinity))
|
|
31
|
+
best = o;
|
|
32
|
+
}
|
|
33
|
+
if (best)
|
|
34
|
+
best.best = true;
|
|
35
|
+
return options.sort((a, b) => {
|
|
36
|
+
const pa = a.actionable && a.price != null ? a.price : Infinity;
|
|
37
|
+
const pb = b.actionable && b.price != null ? b.price : Infinity;
|
|
38
|
+
return pa - pb;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function toOption(row, c, input) {
|
|
42
|
+
const actionable = row.actionable !== false && row.price > 0;
|
|
43
|
+
const name = c?.name ?? row.partner_name ?? row.partner_id;
|
|
44
|
+
const issues = [];
|
|
45
|
+
if (c) {
|
|
46
|
+
const elig = input.mode === 'real' ? c.eligibility.real : c.eligibility.paper;
|
|
47
|
+
for (const i of elig.issues)
|
|
48
|
+
issues.push(fromServerIssue(i));
|
|
49
|
+
if (input.mode === 'real' && c.orders_allowed && !c.order_types.includes(input.orderType)) {
|
|
50
|
+
issues.push(localIssue('order_type_unsupported', { venue: name, detail: input.orderType }));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else if (input.constraints) {
|
|
54
|
+
// The position quotes a venue the constraints document does not list (an
|
|
55
|
+
// inactive or unknown partner). Real money cannot be sent there.
|
|
56
|
+
if (input.mode === 'real')
|
|
57
|
+
issues.push(localIssue('orders_not_supported', { venue: name }, { scope: 'venue' }));
|
|
58
|
+
}
|
|
59
|
+
if (input.mode === 'paper' && input.orderType === 'limit') {
|
|
60
|
+
issues.push(localIssue('paper_limit_unsupported', { venue: name }));
|
|
61
|
+
}
|
|
62
|
+
if (!actionable)
|
|
63
|
+
issues.push(localIssue('no_quote', { venue: name }));
|
|
64
|
+
const status = issues.some((i) => i.severity === 'block') ? 'blocked' : issues.some((i) => i.severity === 'warn') ? 'warn' : 'ok';
|
|
65
|
+
const modes = [];
|
|
66
|
+
if (c ? c.eligibility.paper.ok : true)
|
|
67
|
+
modes.push('paper');
|
|
68
|
+
if (c ? c.eligibility.real.ok : false)
|
|
69
|
+
modes.push('real');
|
|
70
|
+
return {
|
|
71
|
+
partnerId: row.partner_id,
|
|
72
|
+
name,
|
|
73
|
+
logoUrl: c?.logo_url ?? null,
|
|
74
|
+
liquidityHash: row.liquidity_hash ?? null,
|
|
75
|
+
buyId: row.buy_id ?? null,
|
|
76
|
+
price: actionable ? row.price : null,
|
|
77
|
+
americanOdds: row.american_odds ?? null,
|
|
78
|
+
available: actionable ? row.available : null,
|
|
79
|
+
actionable,
|
|
80
|
+
feePacket: row.fee_packet ?? null,
|
|
81
|
+
account: {
|
|
82
|
+
connected: c?.account.connected ?? false,
|
|
83
|
+
status: c?.account.status ?? null,
|
|
84
|
+
credentialStatus: c?.account.credential_status ?? null,
|
|
85
|
+
currency: c?.account.currency ?? null,
|
|
86
|
+
balance: c?.account.balance ?? null,
|
|
87
|
+
expectedBalance: c?.account.expected_balance ?? null,
|
|
88
|
+
stale: c?.account.is_stale ?? true,
|
|
89
|
+
scopeTradeExecute: c?.account.scope_trade_execute ?? true,
|
|
90
|
+
},
|
|
91
|
+
supports: {
|
|
92
|
+
orderTypes: c ? [...c.order_types] : ['market'],
|
|
93
|
+
cancel: c?.cancel_supported ?? false,
|
|
94
|
+
modes,
|
|
95
|
+
},
|
|
96
|
+
eligibility: { status, issues },
|
|
97
|
+
constraints: c,
|
|
98
|
+
best: false,
|
|
99
|
+
selected: input.selectedPartnerId === row.partner_id,
|
|
100
|
+
display: { price: formatPrice(actionable ? row.price : null, input.oddsFormat, row.american_odds) },
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=venues.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"venues.js","sourceRoot":"","sources":["../src/venues.ts"],"names":[],"mappings":"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"}
|