From a2ebade63f3a0af25a5d560e673b35acc788e993 Mon Sep 17 00:00:00 2001 From: Diogo Ferreira Date: Thu, 16 May 2024 17:11:45 +0100 Subject: [PATCH] Improve folder structure and name (#29) * rename model folder to contracts * move models into entities * - rename PositionModel to Position - rename MarketModel to Market * - move contracts into hooks, since they hooks to connects with contracts - move tradeTypeMathOperation into trade file since it's not a hook, rename it to tradeValue --- README.md | 15 +++++++++++++++ app/components/CardBet.tsx | 13 ++++++------- app/components/ConfirmTrade.tsx | 6 ++++-- app/components/Swapbox.tsx | 7 +++---- app/components/UserBets.tsx | 19 +++++++++---------- app/markets/MarketDetails.tsx | 4 ++-- entities/index.ts | 5 ++--- entities/markets/index.ts | 4 ++++ .../Market.ts => entities/markets/market.ts | 2 +- entities/{ => markets}/outcome.ts | 0 .../markets/position.ts | 6 +++--- entities/markets/trade.ts | 8 ++++++++ entities/{ => tokens}/baseCurrency.ts | 0 entities/{ => tokens}/currency.ts | 0 entities/tokens/index.ts | 2 ++ entities/{ => tokens}/nativeCurrency.ts | 0 entities/{ => tokens}/token.ts | 0 .../contracts}/conditionalTokens.ts | 0 hooks/contracts/index.ts | 2 ++ {model => hooks/contracts}/market.ts | 8 -------- models/index.ts | 2 -- 21 files changed, 61 insertions(+), 42 deletions(-) create mode 100644 entities/markets/index.ts rename models/Market.ts => entities/markets/market.ts (97%) rename entities/{ => markets}/outcome.ts (100%) rename models/Position.ts => entities/markets/position.ts (66%) create mode 100644 entities/markets/trade.ts rename entities/{ => tokens}/baseCurrency.ts (100%) rename entities/{ => tokens}/currency.ts (100%) create mode 100644 entities/tokens/index.ts rename entities/{ => tokens}/nativeCurrency.ts (100%) rename entities/{ => tokens}/token.ts (100%) rename {model => hooks/contracts}/conditionalTokens.ts (100%) create mode 100644 hooks/contracts/index.ts rename {model => hooks/contracts}/market.ts (79%) delete mode 100644 models/index.ts diff --git a/README.md b/README.md index 74511226..d2b589a9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Next dapp starter kit + This is a template meant to kickstart dapps. ![Next dapp starter kit](/public/next-dapp-starter-kit.png) @@ -25,3 +26,17 @@ Run the development server: ```bash bun dev ``` + +## Folder structure + +### Entities + +Entities is where business logic lives. Instead of having that spread out on components we create classes with logic. + +**Markets** + +Logic associated with Omen markets like Outcome, Position and Market. + +**Tokens** + +Logic related to blockchain tokens like Token, Currency, NativeCurrency diff --git a/app/components/CardBet.tsx b/app/components/CardBet.tsx index c0eca41a..fb5255be 100644 --- a/app/components/CardBet.tsx +++ b/app/components/CardBet.tsx @@ -12,10 +12,9 @@ import { Card } from "@/app/components/ui"; import { UserPosition } from "@/queries/conditional-tokens/types"; import { getConditionMarket, getMarketUserTrades } from "@/queries/omen"; import { remainingTime } from "@/utils/dates"; -import { MarketModel, PositionModel } from "@/models"; -import { tradeTypeMathOperation } from "@/model/market"; +import { Market, Position, valueByTrade } from "@/entities"; +import { redeemPositions } from "@/hooks/contracts"; import { WXDAI } from "@/constants"; -import { redeemPositions } from "@/model/conditionalTokens"; import { waitForTransactionReceipt } from "wagmi/actions"; import { useState } from "react"; import { ModalId, useModalContext } from "@/context/ModalContext"; @@ -26,7 +25,7 @@ interface BetProps { } export const CardBet = ({ userPosition }: BetProps) => { - const position = new PositionModel(userPosition.position); + const position = new Position(userPosition.position); const config = useConfig(); const { address } = useAccount(); @@ -45,7 +44,7 @@ export const CardBet = ({ userPosition }: BetProps) => { const market = data?.conditions[0] && - new MarketModel(data?.conditions[0]?.fixedProductMarketMakers[0]); + new Market(data?.conditions[0]?.fixedProductMarketMakers[0]); const outcomeIndex = position.outcomeIndex - 1; @@ -66,7 +65,7 @@ export const CardBet = ({ userPosition }: BetProps) => { userTrades?.fpmmTrades.reduce((acc, trade) => { const type = trade.type; const collateralAmountUSD = parseFloat(trade.collateralAmountUSD); - return tradeTypeMathOperation[type](acc, collateralAmountUSD); + return valueByTrade[type](acc, collateralAmountUSD); }, 0) ?? 0; const outcomeBalance = @@ -75,7 +74,7 @@ export const CardBet = ({ userPosition }: BetProps) => { const collateralAmountUSD = parseFloat( formatEther(trade.outcomeTokensTraded as bigint) ); - return tradeTypeMathOperation[type](acc, collateralAmountUSD); + return valueByTrade[type](acc, collateralAmountUSD); }, 0) ?? 0; const balance = outcomeBalance ? outcomeBalance.toFixed(2) : "-"; diff --git a/app/components/ConfirmTrade.tsx b/app/components/ConfirmTrade.tsx index 891e9930..44d99d31 100644 --- a/app/components/ConfirmTrade.tsx +++ b/app/components/ConfirmTrade.tsx @@ -13,12 +13,14 @@ import { SLIPPAGE, SwapDirection, SwapState } from "."; import { useState } from "react"; import { waitForTransactionReceipt, writeContract } from "wagmi/actions"; import MarketABI from "@/abi/market.json"; -import { CONDITIONAL_TOKEN_CONTRACT_ADDRESS } from "@/model/conditionalTokens"; +import { + CONDITIONAL_TOKEN_CONTRACT_ADDRESS, + useReadCalcSellAmount, +} from "@/hooks/contracts"; import ConditionalTokensABI from "@/abi/conditionalTokens.json"; import { addFraction, removeFraction } from "@/utils/price"; import { useConfig } from "wagmi"; import { Address, erc20Abi, formatEther, parseEther } from "viem"; -import { useReadCalcSellAmount } from "@/model/market"; import { WXDAI } from "@/constants"; import { TransactionModal } from "./TransactionModal"; diff --git a/app/components/Swapbox.tsx b/app/components/Swapbox.tsx index 30f2cc8e..15b4d4ca 100644 --- a/app/components/Swapbox.tsx +++ b/app/components/Swapbox.tsx @@ -6,13 +6,13 @@ import { useEffect, useState } from "react"; import { erc20Abi, formatEther, parseEther, Address } from "viem"; import { useAccount, useReadContract } from "wagmi"; import { ConnectButton } from "."; -import { useReadCalcBuyAmount } from "@/model/market"; import { Outcome, Token } from "@/entities"; import { FixedProductMarketMaker } from "@/queries/omen"; import { CONDITIONAL_TOKEN_CONTRACT_ADDRESS, useReadBalance, -} from "@/model/conditionalTokens"; + useReadCalcBuyAmount, +} from "@/hooks/contracts"; import ConditionalTokensABI from "@/abi/conditionalTokens.json"; import { calcSellAmountInCollateral, @@ -22,7 +22,6 @@ import { import { ConfirmTrade } from "./ConfirmTrade"; import { ModalId, useModalContext } from "@/context/ModalContext"; import { WXDAI } from "@/constants"; -import { MarketModel } from "../../models"; export const SLIPPAGE = 0.01; const ONE_UNIT = "1"; @@ -201,7 +200,7 @@ export const Swapbox = ({ market }: { market: FixedProductMarketMaker }) => { { + onChange={event => { setTokenAmountIn(event.target.value); }} onClick={currentState.changeInToken} diff --git a/app/components/UserBets.tsx b/app/components/UserBets.tsx index 6a9edfb3..bf2c84f2 100644 --- a/app/components/UserBets.tsx +++ b/app/components/UserBets.tsx @@ -3,15 +3,14 @@ import { useAccount } from "wagmi"; import { formatEther } from "viem"; import { cx } from "class-variance-authority"; import { waitForTransactionReceipt } from "wagmi/actions"; -import { MarketModel } from "@/models"; +import { Market, valueByTrade } from "@/entities"; import { useState } from "react"; import { Button, Icon, Logo, Tag } from "swapr-ui"; import { WXDAI } from "@/constants"; import { TransactionModal } from "."; import { ModalId, useModalContext } from "@/context/ModalContext"; import { config } from "@/providers/config"; -import { redeemPositions, useReadBalance } from "@/model/conditionalTokens"; -import { tradeTypeMathOperation } from "@/model/market"; +import { redeemPositions, useReadBalance } from "@/hooks/contracts"; import { getCondition } from "@/queries/conditional-tokens"; import { FixedProductMarketMaker, getMarketUserTrades } from "@/queries/omen"; @@ -53,15 +52,15 @@ export const UserBets = ({ market }: UserBets) => { }); const [outcome0UserTrades, outcome1UserTrades] = [ - userTrades?.fpmmTrades.filter((trade) => trade.outcomeIndex === "0") || [], - userTrades?.fpmmTrades.filter((trade) => trade.outcomeIndex === "1") || [], + userTrades?.fpmmTrades.filter(trade => trade.outcomeIndex === "0") || [], + userTrades?.fpmmTrades.filter(trade => trade.outcomeIndex === "1") || [], ]; const outcome0CollateralAmountUSDSpent = outcome0UserTrades.reduce( (acc, trade) => { const type = trade.type; const collateralAmountUSD = parseFloat(trade.collateralAmountUSD); - return tradeTypeMathOperation[type](acc, collateralAmountUSD); + return valueByTrade[type](acc, collateralAmountUSD); }, 0 ); @@ -70,7 +69,7 @@ export const UserBets = ({ market }: UserBets) => { (acc, trade) => { const type = trade.type; const collateralAmountUSD = parseFloat(trade.collateralAmountUSD); - return tradeTypeMathOperation[type](acc, collateralAmountUSD); + return valueByTrade[type](acc, collateralAmountUSD); }, 0 ); @@ -85,7 +84,7 @@ export const UserBets = ({ market }: UserBets) => { const collateralAmountUSD = parseFloat( formatEther(trade.outcomeTokensTraded as bigint) ); - return tradeTypeMathOperation[type](acc, collateralAmountUSD); + return valueByTrade[type](acc, collateralAmountUSD); }, 0); const outcome1TradedBalance = outcome1UserTrades.reduce((acc, trade) => { @@ -93,7 +92,7 @@ export const UserBets = ({ market }: UserBets) => { const collateralAmountUSD = parseFloat( formatEther(trade.outcomeTokensTraded as bigint) ); - return tradeTypeMathOperation[type](acc, collateralAmountUSD); + return valueByTrade[type](acc, collateralAmountUSD); }, 0); const outcomesTradedBalance = [outcome0TradedBalance, outcome1TradedBalance]; @@ -119,7 +118,7 @@ export const UserBets = ({ market }: UserBets) => { ) return null; - const marketModel = new MarketModel(market); + const marketModel = new Market(market); const { condition } = conditionData; const isResolved = condition.resolved; diff --git a/app/markets/MarketDetails.tsx b/app/markets/MarketDetails.tsx index 86f9aa35..4e652c62 100644 --- a/app/markets/MarketDetails.tsx +++ b/app/markets/MarketDetails.tsx @@ -7,7 +7,7 @@ import { Button, IconButton, Tag } from "swapr-ui"; import { remainingTime } from "@/utils/dates"; import Link from "next/link"; import { Address } from "viem"; -import { MarketModel } from "@/models"; +import { Market } from "@/entities"; import { UserBets } from "../components/UserBets"; interface MarketDetailsProps { @@ -25,7 +25,7 @@ export const MarketDetails = ({ id }: MarketDetailsProps) => { return ; const market = data.fixedProductMarketMaker; - const marketModel = new MarketModel(market); + const marketModel = new Market(market); const closingDate = new Date(+market.openingTimestamp * 1000); diff --git a/entities/index.ts b/entities/index.ts index 0ec5e756..21c13047 100644 --- a/entities/index.ts +++ b/entities/index.ts @@ -1,3 +1,2 @@ -export * from "./token"; -export * from "./outcome"; -export * from "./nativeCurrency"; +export * from "./tokens"; +export * from "./markets"; diff --git a/entities/markets/index.ts b/entities/markets/index.ts new file mode 100644 index 00000000..5948e03d --- /dev/null +++ b/entities/markets/index.ts @@ -0,0 +1,4 @@ +export * from "./market"; +export * from "./position"; +export * from "./outcome"; +export * from "./trade"; diff --git a/models/Market.ts b/entities/markets/market.ts similarity index 97% rename from models/Market.ts rename to entities/markets/market.ts index 73b417be..f32b060e 100644 --- a/models/Market.ts +++ b/entities/markets/market.ts @@ -2,7 +2,7 @@ import { FixedProductMarketMaker } from "@/queries/omen"; import { fromHex } from "viem"; import { Outcome } from "@/entities"; -export class MarketModel { +export class Market { data: FixedProductMarketMaker; closingDate: Date; answer: number | null; diff --git a/entities/outcome.ts b/entities/markets/outcome.ts similarity index 100% rename from entities/outcome.ts rename to entities/markets/outcome.ts diff --git a/models/Position.ts b/entities/markets/position.ts similarity index 66% rename from models/Position.ts rename to entities/markets/position.ts index b1be7b7d..9c7eec9e 100644 --- a/models/Position.ts +++ b/entities/markets/position.ts @@ -1,11 +1,11 @@ -import { Position } from "@/queries/conditional-tokens/types"; +import { Position as ConditionalTokenPosition } from "@/queries/conditional-tokens/types"; -export class PositionModel { +export class Position { conditionId: string; outcomeIndex: number; outcomes?: string[] | null; - constructor(position: Position) { + constructor(position: ConditionalTokenPosition) { this.conditionId = position.conditionIdsStr; this.outcomeIndex = position.indexSets[0]; this.outcomes = position.conditions?.[0]?.outcomes; diff --git a/entities/markets/trade.ts b/entities/markets/trade.ts new file mode 100644 index 00000000..155f8a1b --- /dev/null +++ b/entities/markets/trade.ts @@ -0,0 +1,8 @@ +import { TradeType } from "@/queries/omen/types"; + +export const valueByTrade = { + [TradeType.Buy]: (previousValue: number, newValue: number) => + previousValue + newValue, + [TradeType.Sell]: (previousValue: number, newValue: number) => + previousValue - newValue, +}; diff --git a/entities/baseCurrency.ts b/entities/tokens/baseCurrency.ts similarity index 100% rename from entities/baseCurrency.ts rename to entities/tokens/baseCurrency.ts diff --git a/entities/currency.ts b/entities/tokens/currency.ts similarity index 100% rename from entities/currency.ts rename to entities/tokens/currency.ts diff --git a/entities/tokens/index.ts b/entities/tokens/index.ts new file mode 100644 index 00000000..10f99337 --- /dev/null +++ b/entities/tokens/index.ts @@ -0,0 +1,2 @@ +export * from "./token"; +export * from "./nativeCurrency"; diff --git a/entities/nativeCurrency.ts b/entities/tokens/nativeCurrency.ts similarity index 100% rename from entities/nativeCurrency.ts rename to entities/tokens/nativeCurrency.ts diff --git a/entities/token.ts b/entities/tokens/token.ts similarity index 100% rename from entities/token.ts rename to entities/tokens/token.ts diff --git a/model/conditionalTokens.ts b/hooks/contracts/conditionalTokens.ts similarity index 100% rename from model/conditionalTokens.ts rename to hooks/contracts/conditionalTokens.ts diff --git a/hooks/contracts/index.ts b/hooks/contracts/index.ts new file mode 100644 index 00000000..42d5048b --- /dev/null +++ b/hooks/contracts/index.ts @@ -0,0 +1,2 @@ +export * from "./conditionalTokens"; +export * from "./market"; diff --git a/model/market.ts b/hooks/contracts/market.ts similarity index 79% rename from model/market.ts rename to hooks/contracts/market.ts index 17c17b17..84d598e4 100644 --- a/model/market.ts +++ b/hooks/contracts/market.ts @@ -1,7 +1,6 @@ import MarketABI from "@/abi/market.json"; import { Abi, Address, parseEther } from "viem"; import { UseReadContractParameters, useReadContract } from "wagmi"; -import { TradeType } from "@/queries/omen"; export const useReadMarketContract = ({ address, @@ -45,10 +44,3 @@ export const useReadCalcSellAmount = ( query: { enabled: !!tokenOutAmount }, }); }; - -export const tradeTypeMathOperation = { - [TradeType.Buy]: (previousValue: number, newValue: number) => - previousValue + newValue, - [TradeType.Sell]: (previousValue: number, newValue: number) => - previousValue - newValue, -}; diff --git a/models/index.ts b/models/index.ts deleted file mode 100644 index dd5b9b82..00000000 --- a/models/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./Market"; -export * from "./Position";