diff --git a/README.md b/README.md index 24dbcc1..e63475e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Trivex Web -Frontend of **Trivex**, a next-generation decentralized trading platform built on Starknet Layer 3. +Repository for **Trivex**, a next-generation decentralized strategy analysis and trading platform built on Starknet Layer 3. ## 🌐 What is Trivex? @@ -19,7 +19,7 @@ Trivex is designed to onboard both crypto-native users and traditional traders s --- -## Quickstart +## Quickstart for Trivex Frontend ### 1. Clone the Repository @@ -42,16 +42,20 @@ npm run start ## Trivex Smart Contracts +Contains all the smart contracts used by Trivex created with Cairo on Starknet + ```bash -cd trivex_web cd trivex_contract +cd src ``` ## Trivex Titan Bot +Contains the code for titan bot, a bot used to hedge out the orders from users to external broker + ```bash -cd trivex_web -cd trivex titan +cd titan +py titan.py ``` ## 🌐 Community & Support diff --git a/trivex_contract/src/interfaces.cairo b/trivex_contract/src/interfaces.cairo index b2054fd..263c157 100644 --- a/trivex_contract/src/interfaces.cairo +++ b/trivex_contract/src/interfaces.cairo @@ -19,4 +19,8 @@ pub trait ITrivexAction { fn get_total_staked(self: @TContractState) -> Amount; fn get_fee(self: @TContractState, amount: Amount) -> Amount; fn get_apy(self: @TContractState) -> Amount; + fn set_used_balance(ref self: TContractState, value: u256); + fn set_available_balance(ref self: TContractState, value: u256); + fn update_external_order_book(ref self: TContractState, symbol: felt252, leverage: u128, total_value: u256, action: felt252); + fn get_external_order_book(self: @TContractState) -> Array; } \ No newline at end of file diff --git a/trivex_contract/src/trivexaction.cairo b/trivex_contract/src/trivexaction.cairo index 2a389a4..69e4b23 100644 --- a/trivex_contract/src/trivexaction.cairo +++ b/trivex_contract/src/trivexaction.cairo @@ -27,9 +27,13 @@ mod TrivexAction { internal_order_book_len: u256, external_used_balance: u256, external_available_balance: u256, + external_order_book: LegacyMap<(felt252, u128), Amount>, + external_order_book_keys: LegacyMap, + external_order_book_len: u256, lender_interest_rate: u256, strategy_price: LegacyMap, - strategy_creator: LegacyMap + strategy_creator: LegacyMap, + owner: UserAddress } #[constructor] @@ -52,6 +56,9 @@ mod TrivexAction { let key4 = 'coVariance'; self.strategy_price.write(key4, 1_u256); self.strategy_creator.write(key4, creator); + + let owner = contract_address_const::<0x012B099F50C3CbCc82ccF7Ee557c9d60255c35C359eA6615435B761Ec3336EC8>(); + self.owner.write(owner); } #[abi(embed_v0)] @@ -152,7 +159,6 @@ mod TrivexAction { //removing it from positions let count = self.user_position_counts.read(caller); let mut i = id; - let temp = self.positions.read((caller, i)); while i + 1 <= count { let next_pos = self.positions.read((caller, i + 1)); self.positions.write((caller, i), next_pos); @@ -176,11 +182,11 @@ mod TrivexAction { self.user_transaction_counts.write(caller, count_transactions + 1); //updating the internal order book - let current_order_book = self.internal_order_book.read((temp.symbol, temp.leverage)); + let current_order_book = self.internal_order_book.read((position.symbol, position.leverage)); if action == 'Close Buy' { - self.internal_order_book.write((temp.symbol, temp.leverage), current_order_book - amount); + self.internal_order_book.write((position.symbol, position.leverage), current_order_book - amount); } else if action == 'Close Sell' { - self.internal_order_book.write((temp.symbol, temp.leverage), current_order_book + amount); + self.internal_order_book.write((position.symbol, position.leverage), current_order_book + amount); } } } @@ -338,5 +344,62 @@ mod TrivexAction { fn get_apy(self: @ContractState) -> Amount { self.lender_interest_rate.read() } + + fn set_used_balance(ref self: ContractState, value: u256) { + let caller = get_caller_address(); + let owner = self.owner.read(); + assert(caller == owner, 'NOT_OWNER'); + self.external_used_balance.write(value); + } + + fn set_available_balance(ref self: ContractState, value: u256) { + let caller = get_caller_address(); + let owner = self.owner.read(); + assert(caller == owner, 'NOT_OWNER'); + self.external_available_balance.write(value); + } + + fn update_external_order_book(ref self: ContractState, symbol: felt252, leverage: u128, total_value: u256, action: felt252) { + let current_order_book = self.external_order_book.read((symbol, leverage)); + if action == 'Open Buy' { + self.external_order_book.write((symbol, leverage), current_order_book + total_value); + } else if action == 'Open Sell' { + self.external_order_book.write((symbol, leverage), current_order_book - total_value); + } + + if current_order_book == 0 { + let idx = self.external_order_book_len.read(); + self.external_order_book_keys.write(idx, (symbol, leverage)); + self.external_order_book_len.write(idx + 1); + } + } + + fn get_external_order_book(self: @ContractState) -> Array { + let length = self.external_order_book_len.read(); + + let mut entries = ArrayTrait::new(); + let mut i = 0; + + loop { + if i == length { + break; + } + + let key = self.external_order_book_keys.read(i); + let (symbol, leverage) = key; + let amount = self.external_order_book.read(key); + + let entry = order_book_entry { + symbol: symbol, + leverage: leverage, + amount: amount + }; + + entries.append(entry); + i = i + 1; + }; + + entries + } } } diff --git a/trivex_frontend/src/components/AppContract.jsx b/trivex_frontend/src/components/AppContract.jsx index 6c4739c..981a5c5 100644 --- a/trivex_frontend/src/components/AppContract.jsx +++ b/trivex_frontend/src/components/AppContract.jsx @@ -2,8 +2,8 @@ import { Contract, Provider, cairo, CallData, shortString } from 'starknet'; const hash_provider = new Provider({ network: 'sepolia' }); -const classHash = '0x00464f2ddef3ea45129244440b3c21789f38d56b680f0a4d01526a09b0ae3fe8'; -const contractAddress = '0x05083aa7aba0aa78514ac84d70a7c969360a6095189d2fdfaafcb689b4734d38'; +const classHash = '0x044bdb1b55aa0c3e7f1437434e205bfd697405b805e654a68a3fa3adb82e1eeb'; +const contractAddress = '0x031015bf30be2b3e1241bd44b65d6c21fe32255cca3f68b59b5c8a9a0fca3b9b'; const usdcTokenAddress = '0x53b40a647cedfca6ca84f542a0fe36736031905a9639a7f19a3c1e66bfd5080'; const strkTokenAddress = '0x4718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d'; @@ -178,6 +178,7 @@ export class AppContract { datetime: new Date(Number(item.datetime) * 1000) })); + console.log(positions); return positions; } diff --git a/trivex_frontend/src/components/TradingViewWidget.js b/trivex_frontend/src/components/TradingViewWidget.js index 838aff1..985e64e 100644 --- a/trivex_frontend/src/components/TradingViewWidget.js +++ b/trivex_frontend/src/components/TradingViewWidget.js @@ -1,7 +1,7 @@ import React, { useEffect, useRef, memo } from "react"; import { Box } from "@mui/material"; -const TradingViewWidget = ({ symbol = "BTCUSDC"}) => { +const TradingViewWidget = ({ symbol = "BTCUSDT"}) => { const container = useRef(null); useEffect(() => { diff --git a/trivex_frontend/src/pages/StrategyPage.js b/trivex_frontend/src/pages/StrategyPage.js index 06ee8d0..23a9858 100644 --- a/trivex_frontend/src/pages/StrategyPage.js +++ b/trivex_frontend/src/pages/StrategyPage.js @@ -1,4 +1,4 @@ -import React, { useState, useContext} from 'react'; +import React, { useState, useContext, useEffect} from 'react'; import { Box, Typography, TextField, MenuItem, Button, Switch, List, ListItem, ListItemText} from '@mui/material'; import axios from 'axios'; import {AppContext} from '../components/AppProvider'; @@ -25,6 +25,7 @@ const StrategyPage = () => { const [endDate, setEndDate] = useState(''); const [loading, setLoading] = useState(false) + const [strategyPrice, setStrategyPrice] = useState(0); const host = "trivex-strategy-etbga3bramfwgfe9.canadacentral-01.azurewebsites.net"; @@ -55,6 +56,15 @@ const StrategyPage = () => { } }; + const handleStrategyPrice = async (strategy) => { + try { + const amount = await contract.getStrategyPrice(strategy); + setStrategyPrice(amount); + } catch (error) { + alert("An unexpected error occurred. Please try again."); + } +}; + const handleStartAlgo = async () => { if (!strategy) { alert('Please select both a strategy.'); @@ -159,6 +169,11 @@ const StrategyPage = () => { } }; + useEffect(() => { + if (strategy) { + handleStrategyPrice(strategy); + } + }, [strategy]); if(info.walletAddress != null){ return ( @@ -347,6 +362,17 @@ const StrategyPage = () => { )} + + Cost: {strategyPrice} STRK +