diff --git a/package.json b/package.json
index 534768a8..767b5c65 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,7 @@
"pnpm": ">=9.7.0"
},
"dependencies": {
- "@compolabs/spark-orderbook-ts-sdk": "^1.8.2",
+ "@compolabs/spark-orderbook-ts-sdk": "^1.8.4",
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
"@fuels/connectors": "^0.9.1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 349361c1..11e56451 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -9,8 +9,8 @@ importers:
.:
dependencies:
'@compolabs/spark-orderbook-ts-sdk':
- specifier: ^1.8.2
- version: 1.8.2(@types/react@18.3.4)(fuels@0.93.0)(graphql@16.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ specifier: ^1.8.4
+ version: 1.8.4(@types/react@18.3.4)(fuels@0.93.0)(graphql@16.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@emotion/react':
specifier: ^11.11.3
version: 11.13.3(@types/react@18.3.4)(react@18.3.1)
@@ -982,8 +982,8 @@ packages:
'@coinbase/wallet-sdk@4.0.4':
resolution: {integrity: sha512-74c040CRnGhfRjr3ArnkAgud86erIqdkPHNt5HR1k9u97uTIZCJww9eGYT67Qf7gHPpGS/xW8Be1D4dvRm63FA==}
- '@compolabs/spark-orderbook-ts-sdk@1.8.2':
- resolution: {integrity: sha512-i3MKp0ORK8P5lscsqzQ9Wl0yC+y2yB9lGmjD2N7/2guzIq+8KUhjSijdTIZ65SFX7v5ms7ssqFmPnxJOiMQFkA==}
+ '@compolabs/spark-orderbook-ts-sdk@1.8.4':
+ resolution: {integrity: sha512-9YlOQf0G3ikyzxKadZ/ZuuC3WYLOmBFGsPtrLYjnxKBDm06xzJ0GTZp2xJhm02dko2GuweQbEJW5dm7XOOrPHA==}
engines: {node: '>=18'}
peerDependencies:
fuels: '>=0.93.0'
@@ -8247,7 +8247,7 @@ snapshots:
preact: 10.23.2
sha.js: 2.4.11
- '@compolabs/spark-orderbook-ts-sdk@1.8.2(@types/react@18.3.4)(fuels@0.93.0)(graphql@16.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ '@compolabs/spark-orderbook-ts-sdk@1.8.4(@types/react@18.3.4)(fuels@0.93.0)(graphql@16.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@apollo/client': 3.11.8(@types/react@18.3.4)(graphql-ws@5.16.0(graphql@16.9.0))(graphql@16.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
bignumber.js: 9.1.2
diff --git a/src/screens/SpotScreen/OrderbookAndTradesInterface/OrderbookAndTradesInterface.tsx b/src/screens/SpotScreen/OrderbookAndTradesInterface/OrderbookAndTradesInterface.tsx
index c637c242..c7d97a64 100644
--- a/src/screens/SpotScreen/OrderbookAndTradesInterface/OrderbookAndTradesInterface.tsx
+++ b/src/screens/SpotScreen/OrderbookAndTradesInterface/OrderbookAndTradesInterface.tsx
@@ -6,7 +6,6 @@ import SizedBox from "@components/SizedBox";
import Text, { TEXT_TYPES } from "@src/components/Text";
import { SpotOrderBook } from "./SpotOrderBook/SpotOrderBook";
-import { SpotOrderbookVMProvider } from "./SpotOrderBook/SpotOrderbookVM";
import { SpotTrades } from "./SpotTrades/SpotTrades";
import { SpotTradesVMProvider } from "./SpotTrades/SpotTradesVM";
@@ -14,26 +13,24 @@ const OrderbookAndTradesInterface: React.FC = () => {
const [isOrderbook, setIsOrderbook] = useState(true);
return (
-
-
-
-
-
-
-
-
- {isOrderbook ? : }
-
-
-
+
+
+
+
+
+
+
+ {isOrderbook ? : }
+
+
);
};
diff --git a/src/screens/SpotScreen/OrderbookAndTradesInterface/SpotOrderBook/SpotOrderBook.tsx b/src/screens/SpotScreen/OrderbookAndTradesInterface/SpotOrderBook/SpotOrderBook.tsx
index 81aa3f53..491a7511 100644
--- a/src/screens/SpotScreen/OrderbookAndTradesInterface/SpotOrderBook/SpotOrderBook.tsx
+++ b/src/screens/SpotScreen/OrderbookAndTradesInterface/SpotOrderBook/SpotOrderBook.tsx
@@ -24,8 +24,6 @@ import { useStores } from "@stores";
import { ORDER_MODE, useCreateOrderVM } from "../../RightBlock/CreateOrder/CreateOrderVM";
-import { useSpotOrderbookVM } from "./SpotOrderbookVM";
-
interface IProps extends HTMLAttributes {}
export enum SPOT_ORDER_FILTER {
@@ -43,7 +41,7 @@ const SPOT_SETTINGS_ICONS = {
};
export const SpotOrderBook: React.FC = observer(() => {
- const vm = useSpotOrderbookVM();
+ const { spotOrderBookStore } = useStores();
const orderSpotVm = useCreateOrderVM();
const media = useMedia();
const theme = useTheme();
@@ -53,18 +51,19 @@ export const SpotOrderBook: React.FC = observer(() => {
const [isSettingsOpen, openSettings, closeSettings] = useFlag();
useEffect(() => {
- vm.calcSize(media.mobile);
+ spotOrderBookStore.calcSize(media.mobile);
}, [media.mobile]);
const handleCalcSize = useCallback(() => {
- vm.calcSize(media.mobile);
+ spotOrderBookStore.calcSize(media.mobile);
}, [media.mobile]);
useEventListener("resize", handleCalcSize);
- const isOrderBookEmpty = vm.allBuyOrders.length === 0 && vm.allSellOrders.length === 0;
+ const isOrderBookEmpty =
+ spotOrderBookStore.allBuyOrders.length === 0 && spotOrderBookStore.allSellOrders.length === 0;
- if (vm.isOrderBookLoading && isOrderBookEmpty) {
+ if (spotOrderBookStore.isOrderBookLoading && isOrderBookEmpty) {
return ;
}
@@ -85,9 +84,9 @@ export const SpotOrderBook: React.FC = observer(() => {
vm.setOrderFilter(index)}
+ onClick={() => spotOrderBookStore.setOrderFilter(index)}
/>
));
};
@@ -97,9 +96,9 @@ export const SpotOrderBook: React.FC = observer(() => {
return (
- {vm.spreadPrice}
+ {spotOrderBookStore.spreadPrice}
- {`(${vm.spreadPercent}%)`}
+ {`(${spotOrderBookStore.spreadPercent}%)`}
);
}
@@ -107,31 +106,35 @@ export const SpotOrderBook: React.FC = observer(() => {
return (
SPREAD
- {vm.spreadPrice}
- {`(${vm.spreadPercent}%) `}
+ {spotOrderBookStore.spreadPrice}
+ {`(${spotOrderBookStore.spreadPercent}%) `}
);
};
- const indexOfDecimal = SPOT_DECIMAL_OPTIONS.indexOf(vm.decimalGroup);
+ const indexOfDecimal = SPOT_DECIMAL_OPTIONS.indexOf(spotOrderBookStore.decimalGroup);
const handleDecimalSelect = (index: string) => {
const value = SPOT_DECIMAL_OPTIONS[Number(index)];
- vm.setDecimalGroup(value);
+ spotOrderBookStore.setDecimalGroup(value);
};
const renderOrders = (orders: SpotMarketOrder[], type: "sell" | "buy") => {
const orderMode = type === "sell" ? ORDER_MODE.BUY : ORDER_MODE.SELL;
const volumePercent = (ord: SpotMarketOrder) =>
- type === "sell" ? ord.initialAmount.div(vm.totalSell) : ord.initialQuoteAmount.div(vm.totalBuy);
+ type === "sell"
+ ? ord.initialAmount.div(spotOrderBookStore.totalSell)
+ : ord.initialQuoteAmount.div(spotOrderBookStore.totalBuy);
const color = type === "sell" ? theme.colors.redLight : theme.colors.greenLight;
return orders.map((o, index) => (
orderSpotVm.selectOrderbookOrder(o, orderMode)}>
{o.currentAmountUnits.toFormat(4)}
- {o.priceUnits.toFormat(vm.decimalGroup)}
- {numeral(o.currentQuoteAmountUnits).format(`0.${"0".repeat(vm.decimalGroup)}a`)}
+ {o.priceUnits.toFormat(spotOrderBookStore.decimalGroup)}
+
+ {numeral(o.currentQuoteAmountUnits).format(`0.${"0".repeat(spotOrderBookStore.decimalGroup)}a`)}
+
));
};
@@ -156,33 +159,56 @@ export const SpotOrderBook: React.FC = observer(() => {
{`Total ${market?.quoteToken.symbol}`}
- {vm.orderFilter === SPOT_ORDER_FILTER.SELL_AND_BUY && (
+ {spotOrderBookStore.orderFilter === SPOT_ORDER_FILTER.SELL_AND_BUY && (
)}
- {vm.orderFilter === SPOT_ORDER_FILTER.SELL && (
+ {spotOrderBookStore.orderFilter === SPOT_ORDER_FILTER.SELL && (
)}
- {vm.orderFilter !== SPOT_ORDER_FILTER.BUY && renderOrders(vm.sellOrders, "sell")}
+ {spotOrderBookStore.orderFilter !== SPOT_ORDER_FILTER.BUY &&
+ renderOrders(spotOrderBookStore.sellOrders, "sell")}
- {vm.orderFilter === SPOT_ORDER_FILTER.SELL_AND_BUY && renderSpread()}
+ {spotOrderBookStore.orderFilter === SPOT_ORDER_FILTER.SELL_AND_BUY && renderSpread()}
- {vm.orderFilter !== SPOT_ORDER_FILTER.SELL && renderOrders(vm.buyOrders, "buy")}
+ {spotOrderBookStore.orderFilter !== SPOT_ORDER_FILTER.SELL &&
+ renderOrders(spotOrderBookStore.buyOrders, "buy")}
- {vm.orderFilter === SPOT_ORDER_FILTER.BUY && (
+ {spotOrderBookStore.orderFilter === SPOT_ORDER_FILTER.BUY && (
)}
- {vm.orderFilter === SPOT_ORDER_FILTER.SELL_AND_BUY && (
-
+ {spotOrderBookStore.orderFilter === SPOT_ORDER_FILTER.SELL_AND_BUY && (
+
)}
@@ -191,10 +217,10 @@ export const SpotOrderBook: React.FC = observer(() => {
filterIcons={Object.entries(SPOT_SETTINGS_ICONS).map(([key, value]) => value)}
isOpen={isSettingsOpen}
selectedDecimal={String(indexOfDecimal)}
- selectedFilter={vm.orderFilter}
+ selectedFilter={spotOrderBookStore.orderFilter}
onClose={closeSettings}
onDecimalSelect={handleDecimalSelect}
- onFilterSelect={vm.setOrderFilter}
+ onFilterSelect={spotOrderBookStore.setOrderFilter}
/>
diff --git a/src/screens/SpotScreen/RightBlock/CreateOrder/CreateOrder.tsx b/src/screens/SpotScreen/RightBlock/CreateOrder/CreateOrder.tsx
index b2b9fac4..2bcf8ef2 100644
--- a/src/screens/SpotScreen/RightBlock/CreateOrder/CreateOrder.tsx
+++ b/src/screens/SpotScreen/RightBlock/CreateOrder/CreateOrder.tsx
@@ -126,6 +126,7 @@ const CreateOrder: React.FC = observer(() => {
};
const renderInstruction = () => {
+ if (settingsStore.orderType === ORDER_TYPE.Market) return <>>;
const handleChangeTimeInForce = (e: any) => {
settingsStore.setTimeInForce(e);
};
diff --git a/src/screens/SpotScreen/RightBlock/CreateOrder/CreateOrderVM.tsx b/src/screens/SpotScreen/RightBlock/CreateOrder/CreateOrderVM.tsx
index 7d435140..35baa702 100644
--- a/src/screens/SpotScreen/RightBlock/CreateOrder/CreateOrderVM.tsx
+++ b/src/screens/SpotScreen/RightBlock/CreateOrder/CreateOrderVM.tsx
@@ -89,17 +89,18 @@ class CreateOrderVM {
() => oracleStore.prices,
() => {
const { orderType } = settingsStore;
- const token = tradeStore.market?.baseToken;
- const price = token?.priceFeed ? oracleStore.getTokenIndexPrice(token?.priceFeed) : BN.ZERO;
-
+ const { spotOrderBookStore } = this.rootStore;
+ const order = this.isSell
+ ? spotOrderBookStore.buyOrders[0]
+ : spotOrderBookStore.sellOrders[spotOrderBookStore.sellOrders.length - 1];
if (orderType === ORDER_TYPE.Market) {
- this.setInputPriceThrottle(price);
+ this.setInputPriceThrottle(order.price);
} else if (
orderType === ORDER_TYPE.Limit &&
this.inputPrice.isZero() &&
this.activeInput !== ACTIVE_INPUT.Price
) {
- this.setInputPriceThrottle(price);
+ this.setInputPriceThrottle(order.price);
}
},
);
@@ -363,8 +364,6 @@ class CreateOrderVM {
...deposit,
};
- console.log(order);
-
const data = await bcNetwork.createSpotOrderWithDeposit(order, marketContracts);
return data.transactionId;
};
@@ -383,27 +382,42 @@ class CreateOrderVM {
asset: market.baseToken.assetId ?? "",
status: ["Active"],
};
+ const isBuy = type === OrderType.Buy;
- const oppositeOrderType = type === OrderType.Buy ? OrderType.Sell : OrderType.Buy;
+ const oppositeOrderType = isBuy ? OrderType.Sell : OrderType.Buy;
const orders = await bcNetwork.fetchSpotOrders({ ...params, orderType: oppositeOrderType });
+ let total = this.inputTotal;
+ let spend = BN.ZERO;
+ const orderList = orders
+ .map((el) => {
+ if (total.toNumber() < 0) {
+ return null;
+ }
+ spend = spend.plus(el.currentAmount);
+ total = total.minus(el.currentQuoteAmount);
+ return el;
+ })
+ .filter((el) => el !== null);
const price =
settingsStore.orderType === ORDER_TYPE.Market
- ? orders[orders.length - 1].price.toString()
+ ? orderList[orderList.length - 1].price.toString()
: this.inputPrice.toString();
+ deposit = {
+ ...deposit,
+ amountToSpend: this.inputAmount.toString(),
+ };
+
const order: FulfillOrderManyWithDepositParams = {
amount: this.inputAmount.toString(),
orderType: type,
limitType: settingsStore.timeInForce,
price,
- orders: orders.map((el) => el.id),
+ orders: orderList.map((el) => el.id),
slippage: "10000",
...deposit,
};
-
- console.log(order);
-
const data = await bcNetwork.fulfillOrderManyWithDeposit(order, marketContracts);
return data.transactionId;
};
diff --git a/src/screens/SpotScreen/SpotScreenMobile.tsx b/src/screens/SpotScreen/SpotScreenMobile.tsx
index 02c6ad12..0e2d595b 100644
--- a/src/screens/SpotScreen/SpotScreenMobile.tsx
+++ b/src/screens/SpotScreen/SpotScreenMobile.tsx
@@ -12,7 +12,6 @@ import { media } from "@src/themes/breakpoints";
import { useStores } from "@stores";
import { SpotOrderBook } from "./OrderbookAndTradesInterface/SpotOrderBook/SpotOrderBook";
-import { SpotOrderbookVMProvider } from "./OrderbookAndTradesInterface/SpotOrderBook/SpotOrderbookVM";
import CreateOrder from "./RightBlock/CreateOrder";
import MarketSelection from "./RightBlock/MarketSelection";
import MarketStatistics from "./MarketStatistics";
@@ -38,9 +37,7 @@ const SpotScreenMobile: React.FC = observer(() => {
return (
-
-
-
+
diff --git a/src/screens/SwapScreen/SwapScreen.tsx b/src/screens/SwapScreen/SwapScreen.tsx
index ad24a75d..2b1744f4 100644
--- a/src/screens/SwapScreen/SwapScreen.tsx
+++ b/src/screens/SwapScreen/SwapScreen.tsx
@@ -30,7 +30,7 @@ export const SwapScreen: React.FC = observer(() => {
const { isConnected } = useWallet();
const theme = useTheme();
const media = useMedia();
- const { swapStore, balanceStore, quickAssetsStore, tradeStore } = useStores();
+ const { swapStore, balanceStore, tradeStore, spotOrderBookStore } = useStores();
const [isConnectDialogVisible, openConnectDialog, closeConnectDialog] = useFlag();
const bcNetwork = FuelNetwork.getInstance();
const [slippage, setSlippage] = useState(INITIAL_SLIPPAGE);
@@ -76,14 +76,6 @@ export const SwapScreen: React.FC = observer(() => {
return d.length > 0 ? d.filter((el) => assets.some((item) => item.assetId === el.assetId)) : [];
};
- const getMarketPair = (baseAsset: Token, queryAsset: Token) => {
- return markets.find(
- (el) =>
- (el.baseToken.assetId === baseAsset.assetId && el.quoteToken.assetId === queryAsset.assetId) ||
- (el.baseToken.assetId === queryAsset.assetId && el.quoteToken.assetId === baseAsset.assetId),
- );
- };
-
const onPayAmountChange = (e: React.ChangeEvent) => {
setOnPress(false);
const newPayAmount = replaceComma(e.target.value);
@@ -93,9 +85,11 @@ export const SwapScreen: React.FC = observer(() => {
}
swapStore.setPayAmount(newPayAmount);
-
- const receiveAmount =
- Number(newPayAmount) * (parseNumberWithCommas(sellTokenPrice) / parseNumberWithCommas(buyTokenPrice));
+ const isBuy = swapStore.isBuy;
+ const price = !isBuy()
+ ? spotOrderBookStore.buyOrders[0].price
+ : spotOrderBookStore.sellOrders[spotOrderBookStore.sellOrders.length - 1].price;
+ const receiveAmount = BN.parseUnits(new BN(newPayAmount).dividedBy(price), DEFAULT_DECIMALS);
swapStore.setReceiveAmount(receiveAmount.toFixed(swapStore.buyToken.precision));
};
@@ -109,8 +103,11 @@ export const SwapScreen: React.FC = observer(() => {
swapStore.setReceiveAmount(newReceiveAmount);
- const payAmount =
- Number(newReceiveAmount) * (parseNumberWithCommas(buyTokenPrice) / parseNumberWithCommas(sellTokenPrice));
+ const isBuy = swapStore.isBuy;
+ const price = !isBuy()
+ ? spotOrderBookStore.buyOrders[0].price
+ : spotOrderBookStore.sellOrders[spotOrderBookStore.sellOrders.length - 1].price;
+ const payAmount = BN.parseUnits(new BN(newReceiveAmount).dividedBy(price), DEFAULT_DECIMALS);
swapStore.setPayAmount(payAmount.toFixed(swapStore.sellToken.precision));
};
@@ -139,6 +136,7 @@ export const SwapScreen: React.FC = observer(() => {
swapStore.setReceiveAmount("0");
}
} catch (err) {
+ setIsloading(false);
console.error("er", err);
}
};
@@ -155,7 +153,7 @@ export const SwapScreen: React.FC = observer(() => {
swapStore.setBuyToken(type === "sell" ? paris[0] : pair);
swapStore.setPayAmount("0");
swapStore.setReceiveAmount("0");
- const marketId = getMarketPair(pair, paris[0]);
+ const marketId = swapStore.getMarketPair(pair, paris[0]);
if (!marketId) return;
tradeStore.selectActiveMarket(marketId.symbol);
balanceStore.update();
@@ -183,7 +181,7 @@ export const SwapScreen: React.FC = observer(() => {
{
handleChangeMarketId(tokens, item, "sell");
@@ -217,7 +215,7 @@ export const SwapScreen: React.FC = observer(() => {
{
handleChangeMarketId(buyTokenOptions, item, "buy");
diff --git a/src/stores/RootStore.ts b/src/stores/RootStore.ts
index 2c69e9da..ecc1bd29 100644
--- a/src/stores/RootStore.ts
+++ b/src/stores/RootStore.ts
@@ -13,6 +13,7 @@ import { BalanceStore } from "./BalanceStore";
import { ModalStore } from "./ModalStore";
import OracleStore from "./OracleStore";
import SwapStore from "./SwapStore";
+import SpotOrderBookStore from "./SpotOrderBookStore";
export interface ISerializedRootStore {
accountStore?: ISerializedAccountStore;
@@ -33,6 +34,7 @@ export default class RootStore {
swapStore: SwapStore;
mixPanelStore: MixPanelStore;
quickAssetsStore: QuickAssetsStore;
+ spotOrderBookStore: SpotOrderBookStore;
private constructor(initState?: ISerializedRootStore) {
this.notificationStore = new NotificationStore(this);
@@ -46,6 +48,7 @@ export default class RootStore {
this.swapStore = new SwapStore(this);
this.mixPanelStore = new MixPanelStore(this);
this.quickAssetsStore = new QuickAssetsStore(this);
+ this.spotOrderBookStore = new SpotOrderBookStore(this);
makeAutoObservable(this);
diff --git a/src/screens/SpotScreen/OrderbookAndTradesInterface/SpotOrderBook/SpotOrderbookVM.tsx b/src/stores/SpotOrderBookStore.ts
similarity index 91%
rename from src/screens/SpotScreen/OrderbookAndTradesInterface/SpotOrderBook/SpotOrderbookVM.tsx
rename to src/stores/SpotOrderBookStore.ts
index 3178ff6c..60e6950e 100644
--- a/src/screens/SpotScreen/OrderbookAndTradesInterface/SpotOrderBook/SpotOrderbookVM.tsx
+++ b/src/stores/SpotOrderBookStore.ts
@@ -1,4 +1,4 @@
-import React, { useMemo } from "react";
+import React from "react";
import { GetActiveOrdersParams, OrderType } from "@compolabs/spark-orderbook-ts-sdk";
import { makeAutoObservable, reaction } from "mobx";
import { Nullable } from "tsdef";
@@ -6,30 +6,19 @@ import { Nullable } from "tsdef";
import { FuelNetwork } from "@src/blockchain";
import { DEFAULT_DECIMALS } from "@src/constants";
import { SpotMarketOrder } from "@src/entity";
-import useVM from "@src/hooks/useVM";
import { Subscription } from "@src/typings/utils";
import BN from "@src/utils/BN";
import { formatSpotMarketOrders } from "@src/utils/formatSpotMarketOrders";
import { groupOrders } from "@src/utils/groupOrders";
-import { RootStore, useStores } from "@stores";
+import { RootStore } from "@stores";
-import { SPOT_ORDER_FILTER } from "./SpotOrderBook";
-
-const ctx = React.createContext(null);
+import { SPOT_ORDER_FILTER } from "@src/screens/SpotScreen/OrderbookAndTradesInterface/SpotOrderBook/SpotOrderBook";
interface IProps {
children: React.ReactNode;
}
-export const SpotOrderbookVMProvider: React.FC = ({ children }) => {
- const rootStore = useStores();
- const store = useMemo(() => new SpotOrderbookVM(rootStore), [rootStore]);
- return {children};
-};
-
-export const useSpotOrderbookVM = () => useVM(ctx);
-
-class SpotOrderbookVM {
+class SpotOrderBookStore {
private readonly rootStore: RootStore;
allBuyOrders: SpotMarketOrder[] = [];
@@ -208,3 +197,5 @@ class SpotOrderbookVM {
return spread.div(maxBuyPrice).times(100).toFormat(2);
}
}
+
+export default SpotOrderBookStore;
diff --git a/src/stores/SwapStore.ts b/src/stores/SwapStore.ts
index 907e6fbb..75627c40 100644
--- a/src/stores/SwapStore.ts
+++ b/src/stores/SwapStore.ts
@@ -1,4 +1,4 @@
-import { FulfillOrderManyParams, GetOrdersParams, LimitType, OrderType } from "@compolabs/spark-orderbook-ts-sdk";
+import { AssetType, GetOrdersParams, LimitType, OrderType } from "@compolabs/spark-orderbook-ts-sdk";
import { autorun, makeAutoObservable, reaction } from "mobx";
import { FuelNetwork } from "@src/blockchain";
@@ -90,6 +90,15 @@ class SwapStore {
: "0";
}
+ getMarketPair = (baseAsset: Token, quoteToken: Token) => {
+ const { tradeStore } = this.rootStore;
+ return tradeStore.spotMarkets.find(
+ (el) =>
+ (el.baseToken.assetId === baseAsset.assetId && el.quoteToken.assetId === quoteToken.assetId) ||
+ (el.baseToken.assetId === quoteToken.assetId && el.quoteToken.assetId === baseAsset.assetId),
+ );
+ };
+
updateTokens() {
const newTokens = this.fetchNewTokens();
this.tokens = newTokens;
@@ -124,7 +133,7 @@ class SwapStore {
fetchExchangeFeeDebounce = _.debounce(this.fetchExchangeFee, 250);
swapTokens = async ({ slippage }: { slippage: number }): Promise => {
- const { notificationStore, tradeStore, oracleStore } = this.rootStore;
+ const { notificationStore, tradeStore } = this.rootStore;
const baseToken = tradeStore.market?.baseToken;
const isBuy = baseToken?.assetId === this.buyToken.assetId;
const bcNetwork = FuelNetwork.getInstance();
@@ -134,21 +143,44 @@ class SwapStore {
status: ["Active"],
};
- const sellOrders = await bcNetwork!.fetchSpotOrders({
+ const orders = await bcNetwork!.fetchSpotOrders({
...params,
orderType: !isBuy ? OrderType.Buy : OrderType.Sell,
});
// TODO: check if there is enough price sum to fulfill the order
-
const formattedAmount = BN.parseUnits(this.payAmount, this.sellToken.decimals).toString();
const formattedVolume = BN.parseUnits(this.receiveAmount, this.buyToken.decimals).toString();
+ const decimalToken = isBuy ? this.buyToken.decimals : this.sellToken.decimals;
+ const depositAmountWithFee = BN.parseUnits(this.exchangeFee, decimalToken).plus(
+ BN.parseUnits(this.rootStore.tradeStore.matcherFee, decimalToken),
+ );
- const order: FulfillOrderManyParams = {
- amount: isBuy ? formattedVolume : formattedAmount,
+ const pair = this.getMarketPair(this.buyToken, this.sellToken);
+ if (!pair) return true;
+ let total = new BN(isBuy ? formattedAmount : formattedVolume);
+ let spend = BN.ZERO;
+ const orderList = orders
+ .map((el) => {
+ if (total.toNumber() < 0) {
+ return null;
+ }
+ spend = spend.plus(el.currentAmount);
+ total = total.minus(el.currentQuoteAmount);
+ return el;
+ })
+ .filter((el) => el !== null);
+
+ const order = {
orderType: isBuy ? OrderType.Buy : OrderType.Sell,
+ amount: isBuy ? formattedVolume : formattedAmount,
+ price: orderList[orderList.length - 1].price.toString(),
+ amountToSpend: isBuy ? formattedVolume : formattedAmount,
+ amountFee: depositAmountWithFee.toString(),
+ depositAssetId: isBuy ? pair?.quoteToken.assetId : pair?.baseToken.assetId,
+ feeAssetId: pair?.quoteToken.assetId,
+ assetType: isBuy ? AssetType.Quote : AssetType.Base,
limitType: LimitType.FOK,
- price: sellOrders[sellOrders.length - 1].price.toString(),
- orders: sellOrders.map((el) => el.id),
+ orders: orderList.map((el) => el.id),
slippage: slippage.toString(),
};
@@ -163,7 +195,8 @@ class SwapStore {
).toSignificant(2);
try {
- const tx = await bcNetwork.swapTokens(order);
+ const marketContracts = CONFIG.APP.markets.map((el) => el.contractId);
+ const tx = await bcNetwork.fulfillOrderManyWithDeposit(order, marketContracts);
notificationStore.success({
text: getActionMessage(ACTION_MESSAGE_TYPE.CREATING_SWAP)(
amountFormatted,
@@ -171,7 +204,7 @@ class SwapStore {
volumeFormatted,
this.buyToken.symbol,
),
- hash: tx.transactionId,
+ hash: "tx.transactionId,",
});
return true;
} catch (error: any) {
@@ -230,11 +263,11 @@ class SwapStore {
return [
{
assetId: market.baseAssetId,
- balance: new BN(marketBalance?.locked?.base ?? 0),
+ balance: new BN(marketBalance?.liquid?.base ?? 0),
},
{
assetId: market.quoteAssetId,
- balance: new BN(marketBalance?.locked?.quote ?? 0),
+ balance: new BN(marketBalance?.liquid?.quote ?? 0),
},
];
})
diff --git a/src/stores/index.ts b/src/stores/index.ts
index 4248ee9b..e2347df2 100644
--- a/src/stores/index.ts
+++ b/src/stores/index.ts
@@ -10,6 +10,7 @@ import QuickAssetsStore from "./QuickAssetsStore";
import RootStore from "./RootStore";
import SettingsStore from "./SettingsStore";
import TradeStore from "./TradeStore";
+import SpotOrderBookStore from "./SpotOrderBookStore";
export {
AccountStore,
@@ -20,6 +21,7 @@ export {
QuickAssetsStore,
RootStore,
SettingsStore,
+ SpotOrderBookStore,
storesContext,
// SpotOrdersStore,
TradeStore,