Skip to content

Commit 5e89629

Browse files
authored
Feat: fix market orders (#139)
1 parent e639e46 commit 5e89629

File tree

12 files changed

+183
-121
lines changed

12 files changed

+183
-121
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"pnpm": ">=9.7.0"
1616
},
1717
"dependencies": {
18-
"@compolabs/spark-orderbook-ts-sdk": "^1.8.2",
18+
"@compolabs/spark-orderbook-ts-sdk": "^1.8.4",
1919
"@emotion/react": "^11.11.3",
2020
"@emotion/styled": "^11.11.0",
2121
"@fuels/connectors": "^0.9.1",

pnpm-lock.yaml

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/screens/SpotScreen/OrderbookAndTradesInterface/OrderbookAndTradesInterface.tsx

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,31 @@ import SizedBox from "@components/SizedBox";
66
import Text, { TEXT_TYPES } from "@src/components/Text";
77

88
import { SpotOrderBook } from "./SpotOrderBook/SpotOrderBook";
9-
import { SpotOrderbookVMProvider } from "./SpotOrderBook/SpotOrderbookVM";
109
import { SpotTrades } from "./SpotTrades/SpotTrades";
1110
import { SpotTradesVMProvider } from "./SpotTrades/SpotTradesVM";
1211

1312
const OrderbookAndTradesInterface: React.FC = () => {
1413
const [isOrderbook, setIsOrderbook] = useState(true);
1514

1615
return (
17-
<SpotOrderbookVMProvider>
18-
<SpotTradesVMProvider>
19-
<Root>
20-
<ButtonGroup style={{ padding: "0 12px" }}>
21-
<Button active={isOrderbook} onClick={() => setIsOrderbook(true)}>
22-
<Text primary={isOrderbook} type={TEXT_TYPES.BUTTON_SECONDARY}>
23-
orderbook
24-
</Text>
25-
</Button>
26-
<Button active={!isOrderbook} onClick={() => setIsOrderbook(false)}>
27-
<Text primary={!isOrderbook} type={TEXT_TYPES.BUTTON_SECONDARY}>
28-
trades
29-
</Text>
30-
</Button>
31-
</ButtonGroup>
32-
<SizedBox height={8} />
33-
{isOrderbook ? <SpotOrderBook /> : <SpotTrades />}
34-
</Root>
35-
</SpotTradesVMProvider>
36-
</SpotOrderbookVMProvider>
16+
<SpotTradesVMProvider>
17+
<Root>
18+
<ButtonGroup style={{ padding: "0 12px" }}>
19+
<Button active={isOrderbook} onClick={() => setIsOrderbook(true)}>
20+
<Text primary={isOrderbook} type={TEXT_TYPES.BUTTON_SECONDARY}>
21+
orderbook
22+
</Text>
23+
</Button>
24+
<Button active={!isOrderbook} onClick={() => setIsOrderbook(false)}>
25+
<Text primary={!isOrderbook} type={TEXT_TYPES.BUTTON_SECONDARY}>
26+
trades
27+
</Text>
28+
</Button>
29+
</ButtonGroup>
30+
<SizedBox height={8} />
31+
{isOrderbook ? <SpotOrderBook /> : <SpotTrades />}
32+
</Root>
33+
</SpotTradesVMProvider>
3734
);
3835
};
3936

src/screens/SpotScreen/OrderbookAndTradesInterface/SpotOrderBook/SpotOrderBook.tsx

Lines changed: 59 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ import { useStores } from "@stores";
2424

2525
import { ORDER_MODE, useCreateOrderVM } from "../../RightBlock/CreateOrder/CreateOrderVM";
2626

27-
import { useSpotOrderbookVM } from "./SpotOrderbookVM";
28-
2927
interface IProps extends HTMLAttributes<HTMLDivElement> {}
3028

3129
export enum SPOT_ORDER_FILTER {
@@ -43,7 +41,7 @@ const SPOT_SETTINGS_ICONS = {
4341
};
4442

4543
export const SpotOrderBook: React.FC<IProps> = observer(() => {
46-
const vm = useSpotOrderbookVM();
44+
const { spotOrderBookStore } = useStores();
4745
const orderSpotVm = useCreateOrderVM();
4846
const media = useMedia();
4947
const theme = useTheme();
@@ -53,18 +51,19 @@ export const SpotOrderBook: React.FC<IProps> = observer(() => {
5351
const [isSettingsOpen, openSettings, closeSettings] = useFlag();
5452

5553
useEffect(() => {
56-
vm.calcSize(media.mobile);
54+
spotOrderBookStore.calcSize(media.mobile);
5755
}, [media.mobile]);
5856

5957
const handleCalcSize = useCallback(() => {
60-
vm.calcSize(media.mobile);
58+
spotOrderBookStore.calcSize(media.mobile);
6159
}, [media.mobile]);
6260

6361
useEventListener("resize", handleCalcSize);
6462

65-
const isOrderBookEmpty = vm.allBuyOrders.length === 0 && vm.allSellOrders.length === 0;
63+
const isOrderBookEmpty =
64+
spotOrderBookStore.allBuyOrders.length === 0 && spotOrderBookStore.allSellOrders.length === 0;
6665

67-
if (vm.isOrderBookLoading && isOrderBookEmpty) {
66+
if (spotOrderBookStore.isOrderBookLoading && isOrderBookEmpty) {
6867
return <Loader size={32} hideText />;
6968
}
7069

@@ -85,9 +84,9 @@ export const SpotOrderBook: React.FC<IProps> = observer(() => {
8584
<SettingIcon
8685
key={index}
8786
alt="filter"
88-
selected={vm.orderFilter === index}
87+
selected={spotOrderBookStore.orderFilter === index}
8988
src={value}
90-
onClick={() => vm.setOrderFilter(index)}
89+
onClick={() => spotOrderBookStore.setOrderFilter(index)}
9190
/>
9291
));
9392
};
@@ -97,41 +96,45 @@ export const SpotOrderBook: React.FC<IProps> = observer(() => {
9796
return (
9897
<SpreadContainer>
9998
<Text type={TEXT_TYPES.H} primary>
100-
{vm.spreadPrice}
99+
{spotOrderBookStore.spreadPrice}
101100
</Text>
102-
<Text>{`(${vm.spreadPercent}%)`}</Text>
101+
<Text>{`(${spotOrderBookStore.spreadPercent}%)`}</Text>
103102
</SpreadContainer>
104103
);
105104
}
106105

107106
return (
108107
<SpreadContainer>
109108
<Text type={TEXT_TYPES.SUPPORTING}>SPREAD</Text>
110-
<Text primary>{vm.spreadPrice}</Text>
111-
<Text>{`(${vm.spreadPercent}%) `}</Text>
109+
<Text primary>{spotOrderBookStore.spreadPrice}</Text>
110+
<Text>{`(${spotOrderBookStore.spreadPercent}%) `}</Text>
112111
</SpreadContainer>
113112
);
114113
};
115114

116-
const indexOfDecimal = SPOT_DECIMAL_OPTIONS.indexOf(vm.decimalGroup);
115+
const indexOfDecimal = SPOT_DECIMAL_OPTIONS.indexOf(spotOrderBookStore.decimalGroup);
117116

118117
const handleDecimalSelect = (index: string) => {
119118
const value = SPOT_DECIMAL_OPTIONS[Number(index)];
120-
vm.setDecimalGroup(value);
119+
spotOrderBookStore.setDecimalGroup(value);
121120
};
122121

123122
const renderOrders = (orders: SpotMarketOrder[], type: "sell" | "buy") => {
124123
const orderMode = type === "sell" ? ORDER_MODE.BUY : ORDER_MODE.SELL;
125124
const volumePercent = (ord: SpotMarketOrder) =>
126-
type === "sell" ? ord.initialAmount.div(vm.totalSell) : ord.initialQuoteAmount.div(vm.totalBuy);
125+
type === "sell"
126+
? ord.initialAmount.div(spotOrderBookStore.totalSell)
127+
: ord.initialQuoteAmount.div(spotOrderBookStore.totalBuy);
127128
const color = type === "sell" ? theme.colors.redLight : theme.colors.greenLight;
128129

129130
return orders.map((o, index) => (
130131
<OrderRow key={index + "order"} type={type} onClick={() => orderSpotVm.selectOrderbookOrder(o, orderMode)}>
131132
<VolumeBar type={type} volumePercent={volumePercent(o).times(100).toNumber()} />
132133
<Text primary>{o.currentAmountUnits.toFormat(4)}</Text>
133-
<TextOverflow color={color}>{o.priceUnits.toFormat(vm.decimalGroup)}</TextOverflow>
134-
<Text primary>{numeral(o.currentQuoteAmountUnits).format(`0.${"0".repeat(vm.decimalGroup)}a`)}</Text>
134+
<TextOverflow color={color}>{o.priceUnits.toFormat(spotOrderBookStore.decimalGroup)}</TextOverflow>
135+
<Text primary>
136+
{numeral(o.currentQuoteAmountUnits).format(`0.${"0".repeat(spotOrderBookStore.decimalGroup)}a`)}
137+
</Text>
135138
</OrderRow>
136139
));
137140
};
@@ -156,33 +159,56 @@ export const SpotOrderBook: React.FC<IProps> = observer(() => {
156159
<Text type={TEXT_TYPES.SUPPORTING}>{`Total ${market?.quoteToken.symbol}`}</Text>
157160
</OrderBookHeader>
158161
<Container
159-
fitContent={vm.orderFilter === SPOT_ORDER_FILTER.SELL || vm.orderFilter === SPOT_ORDER_FILTER.BUY}
160-
reverse={vm.orderFilter === SPOT_ORDER_FILTER.SELL}
162+
fitContent={
163+
spotOrderBookStore.orderFilter === SPOT_ORDER_FILTER.SELL ||
164+
spotOrderBookStore.orderFilter === SPOT_ORDER_FILTER.BUY
165+
}
166+
reverse={spotOrderBookStore.orderFilter === SPOT_ORDER_FILTER.SELL}
161167
>
162-
{vm.orderFilter === SPOT_ORDER_FILTER.SELL_AND_BUY && (
168+
{spotOrderBookStore.orderFilter === SPOT_ORDER_FILTER.SELL_AND_BUY && (
163169
<Plug
164-
length={vm.sellOrders.length < +vm.oneSizeOrders ? +vm.oneSizeOrders - 1 - vm.sellOrders.length : 0}
170+
length={
171+
spotOrderBookStore.sellOrders.length < +spotOrderBookStore.oneSizeOrders
172+
? +spotOrderBookStore.oneSizeOrders - 1 - spotOrderBookStore.sellOrders.length
173+
: 0
174+
}
165175
/>
166176
)}
167-
{vm.orderFilter === SPOT_ORDER_FILTER.SELL && (
177+
{spotOrderBookStore.orderFilter === SPOT_ORDER_FILTER.SELL && (
168178
<Plug
169-
length={vm.sellOrders.length < +vm.amountOfOrders ? +vm.amountOfOrders - 1 - vm.sellOrders.length : 0}
179+
length={
180+
spotOrderBookStore.sellOrders.length < +spotOrderBookStore.amountOfOrders
181+
? +spotOrderBookStore.amountOfOrders - 1 - spotOrderBookStore.sellOrders.length
182+
: 0
183+
}
170184
/>
171185
)}
172186

173-
{vm.orderFilter !== SPOT_ORDER_FILTER.BUY && renderOrders(vm.sellOrders, "sell")}
187+
{spotOrderBookStore.orderFilter !== SPOT_ORDER_FILTER.BUY &&
188+
renderOrders(spotOrderBookStore.sellOrders, "sell")}
174189

175-
{vm.orderFilter === SPOT_ORDER_FILTER.SELL_AND_BUY && renderSpread()}
190+
{spotOrderBookStore.orderFilter === SPOT_ORDER_FILTER.SELL_AND_BUY && renderSpread()}
176191

177-
{vm.orderFilter !== SPOT_ORDER_FILTER.SELL && renderOrders(vm.buyOrders, "buy")}
192+
{spotOrderBookStore.orderFilter !== SPOT_ORDER_FILTER.SELL &&
193+
renderOrders(spotOrderBookStore.buyOrders, "buy")}
178194

179-
{vm.orderFilter === SPOT_ORDER_FILTER.BUY && (
195+
{spotOrderBookStore.orderFilter === SPOT_ORDER_FILTER.BUY && (
180196
<Plug
181-
length={vm.buyOrders.length < +vm.amountOfOrders ? +vm.amountOfOrders - 1 - vm.buyOrders.length : 0}
197+
length={
198+
spotOrderBookStore.buyOrders.length < +spotOrderBookStore.amountOfOrders
199+
? +spotOrderBookStore.amountOfOrders - 1 - spotOrderBookStore.buyOrders.length
200+
: 0
201+
}
182202
/>
183203
)}
184-
{vm.orderFilter === SPOT_ORDER_FILTER.SELL_AND_BUY && (
185-
<Plug length={vm.buyOrders.length < +vm.oneSizeOrders ? +vm.oneSizeOrders - 1 - vm.buyOrders.length : 0} />
204+
{spotOrderBookStore.orderFilter === SPOT_ORDER_FILTER.SELL_AND_BUY && (
205+
<Plug
206+
length={
207+
spotOrderBookStore.buyOrders.length < +spotOrderBookStore.oneSizeOrders
208+
? +spotOrderBookStore.oneSizeOrders - 1 - spotOrderBookStore.buyOrders.length
209+
: 0
210+
}
211+
/>
186212
)}
187213
</Container>
188214

@@ -191,10 +217,10 @@ export const SpotOrderBook: React.FC<IProps> = observer(() => {
191217
filterIcons={Object.entries(SPOT_SETTINGS_ICONS).map(([key, value]) => value)}
192218
isOpen={isSettingsOpen}
193219
selectedDecimal={String(indexOfDecimal)}
194-
selectedFilter={vm.orderFilter}
220+
selectedFilter={spotOrderBookStore.orderFilter}
195221
onClose={closeSettings}
196222
onDecimalSelect={handleDecimalSelect}
197-
onFilterSelect={vm.setOrderFilter}
223+
onFilterSelect={spotOrderBookStore.setOrderFilter}
198224
/>
199225
</OrderbookContainer>
200226
</Root>

src/screens/SpotScreen/RightBlock/CreateOrder/CreateOrder.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ const CreateOrder: React.FC = observer(() => {
126126
};
127127

128128
const renderInstruction = () => {
129+
if (settingsStore.orderType === ORDER_TYPE.Market) return <></>;
129130
const handleChangeTimeInForce = (e: any) => {
130131
settingsStore.setTimeInForce(e);
131132
};

src/screens/SpotScreen/RightBlock/CreateOrder/CreateOrderVM.tsx

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -89,17 +89,18 @@ class CreateOrderVM {
8989
() => oracleStore.prices,
9090
() => {
9191
const { orderType } = settingsStore;
92-
const token = tradeStore.market?.baseToken;
93-
const price = token?.priceFeed ? oracleStore.getTokenIndexPrice(token?.priceFeed) : BN.ZERO;
94-
92+
const { spotOrderBookStore } = this.rootStore;
93+
const order = this.isSell
94+
? spotOrderBookStore.buyOrders[0]
95+
: spotOrderBookStore.sellOrders[spotOrderBookStore.sellOrders.length - 1];
9596
if (orderType === ORDER_TYPE.Market) {
96-
this.setInputPriceThrottle(price);
97+
this.setInputPriceThrottle(order.price);
9798
} else if (
9899
orderType === ORDER_TYPE.Limit &&
99100
this.inputPrice.isZero() &&
100101
this.activeInput !== ACTIVE_INPUT.Price
101102
) {
102-
this.setInputPriceThrottle(price);
103+
this.setInputPriceThrottle(order.price);
103104
}
104105
},
105106
);
@@ -363,8 +364,6 @@ class CreateOrderVM {
363364
...deposit,
364365
};
365366

366-
console.log(order);
367-
368367
const data = await bcNetwork.createSpotOrderWithDeposit(order, marketContracts);
369368
return data.transactionId;
370369
};
@@ -383,27 +382,42 @@ class CreateOrderVM {
383382
asset: market.baseToken.assetId ?? "",
384383
status: ["Active"],
385384
};
385+
const isBuy = type === OrderType.Buy;
386386

387-
const oppositeOrderType = type === OrderType.Buy ? OrderType.Sell : OrderType.Buy;
387+
const oppositeOrderType = isBuy ? OrderType.Sell : OrderType.Buy;
388388
const orders = await bcNetwork.fetchSpotOrders({ ...params, orderType: oppositeOrderType });
389+
let total = this.inputTotal;
390+
let spend = BN.ZERO;
391+
const orderList = orders
392+
.map((el) => {
393+
if (total.toNumber() < 0) {
394+
return null;
395+
}
396+
spend = spend.plus(el.currentAmount);
397+
total = total.minus(el.currentQuoteAmount);
398+
return el;
399+
})
400+
.filter((el) => el !== null);
389401

390402
const price =
391403
settingsStore.orderType === ORDER_TYPE.Market
392-
? orders[orders.length - 1].price.toString()
404+
? orderList[orderList.length - 1].price.toString()
393405
: this.inputPrice.toString();
394406

407+
deposit = {
408+
...deposit,
409+
amountToSpend: this.inputAmount.toString(),
410+
};
411+
395412
const order: FulfillOrderManyWithDepositParams = {
396413
amount: this.inputAmount.toString(),
397414
orderType: type,
398415
limitType: settingsStore.timeInForce,
399416
price,
400-
orders: orders.map((el) => el.id),
417+
orders: orderList.map((el) => el.id),
401418
slippage: "10000",
402419
...deposit,
403420
};
404-
405-
console.log(order);
406-
407421
const data = await bcNetwork.fulfillOrderManyWithDeposit(order, marketContracts);
408422
return data.transactionId;
409423
};

src/screens/SpotScreen/SpotScreenMobile.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { media } from "@src/themes/breakpoints";
1212
import { useStores } from "@stores";
1313

1414
import { SpotOrderBook } from "./OrderbookAndTradesInterface/SpotOrderBook/SpotOrderBook";
15-
import { SpotOrderbookVMProvider } from "./OrderbookAndTradesInterface/SpotOrderBook/SpotOrderbookVM";
1615
import CreateOrder from "./RightBlock/CreateOrder";
1716
import MarketSelection from "./RightBlock/MarketSelection";
1817
import MarketStatistics from "./MarketStatistics";
@@ -38,9 +37,7 @@ const SpotScreenMobile: React.FC = observer(() => {
3837
return (
3938
<MobileContent>
4039
<ContentWrapper>
41-
<SpotOrderbookVMProvider>
42-
<SpotOrderBook />
43-
</SpotOrderbookVMProvider>
40+
<SpotOrderBook />
4441
</ContentWrapper>
4542
<ContentWrapper>
4643
<CreateOrder />

0 commit comments

Comments
 (0)