Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VITE_CONTRACT_ADDRESSES_MARKET=0x08ca18ed550d6229f001641d43aac58e00f9eb7e25c9bea6d33716af61e43b2a
VITE_CONTRACT_ADDRESS_ORDERBOOK=0x164eae2ba74d71f3efb2a9adea4be8803cd464b17be841d2355f9a60301e0ff1
VITE_CONTRACT_ADDRESSES_TOKEN_FACTORY=0x3141a3f11e3f784364d57860e3a4dcf9b73d42e23fd49038773cefb09c633348
VITE_CONTRACT_ADDRESSES_PYTH=0x3cd5005f23321c8ae0ccfa98fb07d9a5ff325c483f21d2d9540d6897007600c9
VITE_INDEXER_URL=indexer.bigdevenergy.link/67b693c
13 changes: 8 additions & 5 deletions .github/workflows/deploy-to-cf-pages.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: Cloudflare Pages Deploy

on:
push:
branches:
Expand All @@ -11,16 +11,18 @@ on:
jobs:
deploy:
environment:
name: ${{ (github.ref == 'refs/heads/main' && 'production') || (github.ref == 'refs/heads/develop' && 'dev') || 'preview' }}
name:
${{ (github.ref == 'refs/heads/main' && 'production') || (github.ref == 'refs/heads/develop' && 'dev') ||
'preview' }}
permissions:
actions: read # Only required for private GitHub Repo
contents: read
deployments: write
pull-requests: write
runs-on: ubuntu-latest
timeout-minutes: 5
timeout-minutes: 5
steps:
- name: 'Checkout Github Action'
- name: "Checkout Github Action"
uses: actions/checkout@v4
- name: Install pnpm
uses: pnpm/action-setup@v4
Expand All @@ -40,12 +42,13 @@ jobs:
echo VITE_CONTRACT_ADDRESSES_MARKET=${{ vars.VITE_CONTRACT_ADDRESSES_MARKET }} >> .env
echo VITE_CONTRACT_ADDRESSES_PYTH=${{ vars.VITE_CONTRACT_ADDRESSES_PYTH }} >> .env
echo VITE_CONTRACT_ADDRESSES_TOKEN_FACTORY=${{ vars.VITE_CONTRACT_ADDRESSES_TOKEN_FACTORY }} >> .env
echo VITE_CONTRACT_ADDRESS_ORDERBOOK=${{ vars.VITE_CONTRACT_ADDRESS_ORDERBOOK }} >> .env
echo VITE_INDEXER_URL=${{ vars.VITE_INDEXER_URL }} >> .env
cat .env
- name: Build Project
run: |
npm run build
- name: 'Deploy to Cloudflare Pages'
- name: "Deploy to Cloudflare Pages"
uses: andykenward/github-actions-cloudflare-pages@v2.3.1
with:
cloudflare-api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"deploy": "gh-pages -d build"
},
"dependencies": {
"@compolabs/spark-orderbook-ts-sdk": "^1.4.8",
"@compolabs/spark-orderbook-ts-sdk": "^1.5.0",
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
"@fuels/connectors": "^0.9.1",
Expand Down
10 changes: 5 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 21 additions & 3 deletions src/blockchain/FuelNetwork.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import {
import {
Balances,
FetchTradesParams,
MarketCreateEvent,
Market,
PerpMaxAbsPositionSize,
PerpPendingFundingPayment,
SpotMarketVolume,
Expand Down Expand Up @@ -66,6 +66,10 @@ export class FuelNetwork {
return FuelNetwork.instance;
}

setActiveMarket = (marketAddress: string) => {
this.orderbookSdk.setActiveMarketAddress(marketAddress);
};

getAddress = (): Nullable<B256Address> => {
return this.walletManager.address;
};
Expand Down Expand Up @@ -189,8 +193,22 @@ export class FuelNetwork {
// await this.sdk.fulfillPerpOrder(gasAsset, orderId, amount, tokenPriceFeed);
};

fetchSpotMarkets = async (limit: number): Promise<MarketCreateEvent[]> => {
return this.orderbookSdk.fetchMarkets(limit);
fetchSpotMarkets = async (): Promise<Market[]> => {
const quoteToken = this.getTokenBySymbol("USDC");
const assetIdList: [string, string][] = this.getTokenList().map((token) => [token.assetId, quoteToken.assetId]);
const markets = await this.orderbookSdk.fetchMarkets(assetIdList);
const marketIdList = assetIdList.map((pair) => markets[pair[0]]).filter(Boolean) as string[];

const marketConfigPromises = marketIdList.map((marketId) => this.orderbookSdk.fetchMarketConfig(marketId));

const marketConfigs = await Promise.all(marketConfigPromises);

return marketConfigs.map((info, index) => ({
id: String(index),
assetId: info.baseAssetId,
decimal: info.priceDecimals,
contractId: marketIdList[index],
}));
};

fetchSpotMarketPrice = async (baseTokenAddress: string): Promise<BN> => {
Expand Down
10 changes: 7 additions & 3 deletions src/blockchain/constants.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import { OrderbookContracts } from "@compolabs/spark-orderbook-ts-sdk";

import TOKEN_LOGOS from "@src/constants/tokenLogos";
import { Token } from "@src/entity/Token";

import TOKENS_JSON from "./tokens.json";

const CONTRACT_ADDRESSES_MARKET = import.meta.env.VITE_CONTRACT_ADDRESSES_MARKET;
const CONTRACT_ADDRESS_ORDERBOOK = import.meta.env.VITE_CONTRACT_ADDRESS_ORDERBOOK;
const CONTRACT_ADDRESSES_TOKEN_FACTORY = import.meta.env.VITE_CONTRACT_ADDRESSES_TOKEN_FACTORY;
const CONTRACT_ADDRESSES_PYTH = import.meta.env.VITE_CONTRACT_ADDRESSES_PYTH;
const INDEXER_URL = import.meta.env.VITE_INDEXER_URL;

export const CONTRACT_ADDRESSES = {
market: CONTRACT_ADDRESSES_MARKET,
export const CONTRACT_ADDRESSES: OrderbookContracts = {
market: "", // Markets will be retrieved from the order book
orderbook: CONTRACT_ADDRESS_ORDERBOOK,
tokenFactory: CONTRACT_ADDRESSES_TOKEN_FACTORY,
pyth: CONTRACT_ADDRESSES_PYTH,
};

export interface Network {
name: string;
url: string;
Expand Down
3 changes: 2 additions & 1 deletion src/blockchain/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ export type FetchTradesParams = {
user?: string;
};

export type MarketCreateEvent = {
export type Market = {
id: string;
assetId: string;
decimal: number;
contractId: string;
};

export type SpotMarketVolume = {
Expand Down
3 changes: 3 additions & 0 deletions src/entity/PerpMarket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ interface PerpMarketParams {
pausedIndexPrice?: BN;
pausedTimestamp?: number;
closedPrice?: BN;
contractAddress: string;
}

export class PerpMarket {
readonly baseToken: Token;
readonly quoteToken: Token;
readonly contractAddress: string;

readonly imRatio: BN;
readonly mmRatio: BN;
Expand All @@ -44,6 +46,7 @@ export class PerpMarket {
this.pausedIndexPrice = params.pausedIndexPrice;
this.pausedTimestamp = params.pausedTimestamp;
this.closedPrice = params.closedPrice;
this.contractAddress = params.contractAddress;

makeAutoObservable(this);
}
Expand Down
5 changes: 4 additions & 1 deletion src/entity/SpotMarket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,18 @@ import { Token } from "./Token";
export class SpotMarket {
readonly baseToken: Token;
readonly quoteToken: Token;
readonly contractAddress: string;

price: BN = BN.ZERO;
setPrice = (price: BN) => (this.price = price);

constructor(baseToken: string, quoteToken: string) {
constructor(baseToken: string, quoteToken: string, contractAddress: string) {
const bcNetwork = FuelNetwork.getInstance();

this.baseToken = bcNetwork.getTokenByAssetId(baseToken);
this.quoteToken = bcNetwork.getTokenByAssetId(quoteToken);
this.contractAddress = contractAddress;

makeAutoObservable(this);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { PropsWithChildren, useMemo } from "react";
import {
AssetType,
CreateOrderParams,
FulfillOrderManyParams,
GetOrdersParams,
Expand Down Expand Up @@ -314,7 +313,6 @@ class CreateOrderVM {
} else {
const order: CreateOrderParams = {
amount: this.inputAmount.toString(),
assetType: AssetType.Base,
price: this.inputPrice.toString(),
type,
feeAssetId: bcNetwork.getTokenBySymbol("ETH").assetId,
Expand All @@ -335,7 +333,6 @@ class CreateOrderVM {

const order: FulfillOrderManyParams = {
amount: this.inputAmount.toString(),
assetType: AssetType.Base,
orderType: type,
limitType: timeInForce,
price:
Expand Down
20 changes: 3 additions & 17 deletions src/screens/TradeScreen/TradeScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { useLocation, useParams } from "react-router-dom";
import { observer } from "mobx-react";

import Loader from "@src/components/Loader";
import { PerpMarket, SpotMarket } from "@src/entity";
import { useMedia } from "@src/hooks/useMedia";
import { CreateOrderVMProvider } from "@src/screens/TradeScreen/RightBlock/CreateOrder/CreateOrderVM";
import { useStores } from "@stores";
Expand All @@ -28,27 +27,14 @@ const TradeScreen: React.FC = observer(() => {
const { marketId } = useParams<{ marketId: string }>();

const isPerp = location.pathname.includes("PERP");

const isMarketExists = (markets: SpotMarket[] | PerpMarket[]) => markets.some((market) => market.symbol === marketId);

const spotMarketExists = isMarketExists(tradeStore.spotMarkets);
const perpMarketExists = isMarketExists(tradeStore.perpMarkets);
useEffect(() => {
tradeStore.selectActiveMarket(isPerp, marketId);
}, [marketId, isPerp]);

if (!tradeStore.initialized) {
return <Loader />;
}

const selectedMarket = !marketId
? tradeStore.defaultMarketSymbol
: spotMarketExists
? marketId
: perpMarketExists
? marketId
: tradeStore.defaultMarketSymbol;

tradeStore.setIsPerp(isPerp && tradeStore.isPerpAvailable);
tradeStore.setMarketSymbol(selectedMarket);

return (
// TradeScreenImpl оборачивается в CreateOrderSpotVMProvider чтобы при нажатии на ордер в OrderbookAndTradesInterface устанавливать значение в RightBlock
<CreateOrderVMProvider>
Expand Down
2 changes: 0 additions & 2 deletions src/stores/SwapStore.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {
AssetType,
FulfillOrderManyParams,
GetOrdersParams,
LimitType,
Expand Down Expand Up @@ -110,7 +109,6 @@ class SwapStore {

const order: FulfillOrderManyParams = {
amount: isBuy ? formattedVolume : formattedAmount,
assetType: AssetType.Base,
orderType: this.buyToken.symbol === "BTC" ? OrderType.Buy : OrderType.Sell,
limitType: LimitType.FOK, // TODO: Check is it correct
price: sellOrders[sellOrders.length - 1].price.toString(),
Expand Down
34 changes: 30 additions & 4 deletions src/stores/TradeStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ class TradeStore {
spotMarkets: SpotMarket[] = [];
perpMarkets: PerpMarket[] = [];
marketSelectionOpened = false;
marketSymbol: Nullable<string> = null;
readonly defaultMarketSymbol = "BTC-USDC";
marketSymbol: string = "BTC-USDC";

isPerp = false;
setIsPerp = (value: boolean) => (this.isPerp = value);
Expand Down Expand Up @@ -89,6 +88,28 @@ class TradeStore {

setMarketSymbol = (v: string) => (this.marketSymbol = v);

selectActiveMarket = (isPerp: boolean, marketId?: string) => {
const bcNetwork = FuelNetwork.getInstance();

const getMarket = <T extends SpotMarket | PerpMarket>(markets: T[]) =>
markets.find((market) => market.symbol === marketId);

const spotMarket = getMarket<SpotMarket>(this.spotMarkets);
const perpMarket = getMarket<PerpMarket>(this.perpMarkets);

if (spotMarket || perpMarket) {
this.setMarketSymbol(marketId!);
}

if (spotMarket) {
bcNetwork.setActiveMarket(spotMarket.contractAddress);
} else if (perpMarket) {
bcNetwork.setActiveMarket(perpMarket.contractAddress);
}

this.setIsPerp(isPerp && this.isPerpAvailable);
};

addToFav = (marketId: string) => {
if (!this.favMarkets.includes(marketId)) {
this.setFavMarkets([...this.favMarkets, marketId]);
Expand Down Expand Up @@ -161,10 +182,15 @@ class TradeStore {
const bcNetwork = FuelNetwork.getInstance();

try {
const markets = await bcNetwork!.fetchSpotMarkets(100);
const markets = await bcNetwork!.fetchSpotMarkets();

const spotMarkets = markets
.filter((market) => bcNetwork!.getTokenByAssetId(market.assetId) !== undefined)
.map((market) => new SpotMarket(market.assetId, bcNetwork!.getTokenBySymbol("USDC").assetId));
.map(
(market) => new SpotMarket(market.assetId, bcNetwork!.getTokenBySymbol("USDC").assetId, market.contractId),
);

bcNetwork.setActiveMarket(markets[0].contractId);

this.setSpotMarkets(spotMarkets);
await this.updateMarketPrices();
Expand Down