diff --git a/src/hooks/contract/lend.ts b/src/hooks/contract/lend.ts new file mode 100644 index 00000000..0529dc44 --- /dev/null +++ b/src/hooks/contract/lend.ts @@ -0,0 +1,33 @@ +import { useState } from "react"; +import { toNano, Address, beginCell } from "@ton/core"; + +import * as Contract from "./transferNFT"; + +export default async function lend(id: number, contract, responseAddress: Address) { + const destination = id >= 100 ? import.meta.env.VITE_LEND_CONTRACT : import.meta.env.VITE_LEND_CONTRACT_OG; + + if (id >= 100) { + await contract.sendWithData( + { + value: toNano("0.102"), + queryId: BigInt(Date.now()), + newOwner: Address.parse(destination), + responseAddress: responseAddress, + fwdAmount: toNano("0.052"), + }, + toNano("0.102"), + ); + } else { + await contract.sendMessage( + { + value: toNano("0.102"), + queryId: BigInt(Date.now()), + newOwner: Address.parse(destination), + responseAddress: responseAddress, + fwdAmount: toNano("0.052"), + fwdPayload: beginCell().storeUint(id, 64), + }, + toNano("0.102"), + ); + } +} diff --git a/src/hooks/contract/repay.js b/src/hooks/contract/repay.js index 2500c20c..74e86563 100644 --- a/src/hooks/contract/repay.js +++ b/src/hooks/contract/repay.js @@ -37,7 +37,10 @@ function repay(id) { isLoading, sendMessage: async param => { if (nftAddress && jettonWallet) { - const lendContractAddress = Address.parse(import.meta.env.VITE_LEND_CONTRACT); + const lendContractAddress = + id >= 100 + ? Address.parse(import.meta.env.VITE_LEND_CONTRACT) + : Address.parse(import.meta.env.VITE_LEND_CONTRACT_OG); await jettonWallet.tokenTransfer(lendContractAddress, { amount: param.amount, fwdAmount: param.forward_ton_amount, @@ -51,4 +54,4 @@ function repay(id) { }; } -export { repay }; \ No newline at end of file +export { repay }; diff --git a/src/hooks/contract/transferNFT.js b/src/hooks/contract/transferNFT.js index 49048a47..857b2637 100644 --- a/src/hooks/contract/transferNFT.js +++ b/src/hooks/contract/transferNFT.js @@ -49,6 +49,7 @@ function transferNft(id) { newOwner: data.newOwner, responseAddress: data.responseAddress, forwardAmount: data.fwdAmount, + forwardPayload: data.fwdPayload, }); await sender.send({ to: nftAddress, @@ -58,7 +59,7 @@ function transferNft(id) { } else { throw new Error("NftAddress not set"); } - } catch { + } catch (error) { throw new Error("Error while sending nft"); } }, diff --git a/src/hooks/contract/wrappers/NftItem.ts b/src/hooks/contract/wrappers/NftItem.ts index ebd6c73b..96375d94 100644 --- a/src/hooks/contract/wrappers/NftItem.ts +++ b/src/hooks/contract/wrappers/NftItem.ts @@ -180,10 +180,10 @@ export class NftItem implements Contract { params: { value: bigint; queryId: bigint; - newOwner: Address; - responseAddress: Address; + newOwnerAddress: Address; + responseDestination: Address; forwardAmount: bigint; - forwardPayload: Builder; + forwardPayload: Builder | null; }, ) { await provider.internal(via, { @@ -191,32 +191,32 @@ export class NftItem implements Contract { body: beginCell() .storeUint(0x5fcc3d14, 32) //operation code .storeUint(params.queryId ?? 0, 64) - .storeAddress(params.newOwner) - .storeAddress(params.responseAddress) + .storeAddress(params.newOwnerAddress) + .storeAddress(params.responseDestination) .storeInt(BigInt(0), 1) //custom payload .storeCoins(params.forwardAmount) - .storeUint(123, 8) + .storeBuilder(params.forwardPayload ?? beginCell().storeUint(1, 4)) .endCell(), }); } static storeTransferWithData(params: { value: bigint; - queryId: bigint; - newOwnerAddress: Address; - responseDestination: Address; - forwardAmount: bigint; - forwardPayload: Builder; - }){ + queryId: bigint; + newOwnerAddress: Address; + responseDestination: Address; + forwardAmount: bigint; + forwardPayload: Builder; + }) { return beginCell() - .storeUint(0x10241a2b, 32) //operation code - .storeUint(params.queryId ?? 0, 64) - .storeAddress(params.newOwnerAddress) - .storeAddress(params.responseDestination) - .storeInt(BigInt(0), 1) //custom payload - .storeCoins(params.forwardAmount) - .storeUint(12, 8) - .endCell() + .storeUint(0x10241a2b, 32) //operation code + .storeUint(params.queryId ?? 0, 64) + .storeAddress(params.newOwnerAddress) + .storeAddress(params.responseDestination) + .storeInt(BigInt(0), 1) //custom payload + .storeCoins(params.forwardAmount) + .storeUint(12, 8) + .endCell(); } static storeTransfer(params: { @@ -226,15 +226,15 @@ export class NftItem implements Contract { responseAddress: Address; forwardAmount: bigint; forwardPayload: Builder; - }){ + }) { return beginCell() - .storeUint(0x5fcc3d14, 32) //operation code - .storeUint(params.queryId ?? 0, 64) - .storeAddress(params.newOwner) - .storeAddress(params.responseAddress) - .storeInt(BigInt(0), 1) //custom payload - .storeCoins(params.forwardAmount) - .storeUint(123, 8) - .endCell() + .storeUint(0x5fcc3d14, 32) //operation code + .storeUint(params.queryId ?? 0, 64) + .storeAddress(params.newOwner) + .storeAddress(params.responseAddress) + .storeInt(BigInt(0), 1) //custom payload + .storeCoins(params.forwardAmount) + .storeBuilder(params.forwardPayload ?? beginCell().storeUint(1, 4)) + .endCell(); } } diff --git a/src/pages/Dashboard/Dashboard.tsx b/src/pages/Dashboard/Dashboard.tsx index 944fa601..c9e975a7 100644 --- a/src/pages/Dashboard/Dashboard.tsx +++ b/src/pages/Dashboard/Dashboard.tsx @@ -2,6 +2,7 @@ import { useEffect, useState } from "react"; import { useLocation, useNavigate } from "react-router-dom"; import { CartesianGrid, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts"; import { useSetRecoilState } from "recoil"; +import styled from "styled-components"; import { ClickAwayListener } from "@mui/material"; //tooltip name이 겹쳐서 변수명 설정해줌 @@ -81,7 +82,7 @@ const Dashboard = () => { } = useBotPerformanceChart(chartTimeFrameOptions[timeFrame]); const { data: tonPriceData, isLoading: tonPriceLoading, error: tonPriceError } = useCoinPrice("ton", "usd"); - + useEffect(() => { if (tele) { tele.ready(); @@ -177,12 +178,69 @@ const Dashboard = () => {

Stakers Win Rate

{performanceData?.pnlWinRate?.toFixed(2)}%

- + +

TVL + + TON+ + + nxTON + + } + placement="top" + slotProps={{ + popper: { + sx: { + [`&.${tooltipClasses.popper}[data-popper-placement*="top"] .${tooltipClasses.tooltip}`]: { + marginBottom: "5px", + }, + }, + }, + }} + componentsProps={{ + tooltip: { + sx: { + padding: "7px 15px", + bgcolor: "#000", + alignContent: "center", + textAlign: "center", + width: "152px", + height: "42px", + transform: "center bottom", + border: "none", + }, + }, + arrow: { sx: { color: "black", border: "none" } }, + }} + arrow + > +
+ +
+

{limitDecimals(performanceData?.tvl, 3)} TON

+
@@ -197,7 +255,9 @@ const Dashboard = () => {

${tonPriceData?.rates?.TON?.prices?.USD.toFixed(2)}

- + {tonPriceData?.rates?.TON?.diff_24h?.USD}
@@ -212,3 +272,24 @@ const Dashboard = () => { }; export default Dashboard; + +const TooltipText = styled.div` + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + + color: var(--Neutral-Neutural-100, #fff); + text-align: right; + font-family: Montserrat; + font-size: 13px; + font-style: normal; + font-weight: 500; + line-height: 18px; /* 138.462% */ + + img { + width: 22px; + height: 22px; + margin-right: 0.2rem; + } +`; diff --git a/src/pages/Loan/Borrow/BorrowVerify.tsx b/src/pages/Loan/Borrow/BorrowVerify.tsx index 252f0549..1abee875 100644 --- a/src/pages/Loan/Borrow/BorrowVerify.tsx +++ b/src/pages/Loan/Borrow/BorrowVerify.tsx @@ -9,6 +9,7 @@ import ProgressBar from "@/components/loan/common/ProgressBar.tsx"; import StakingInfo from "@/components/loan/common/StakingInfo.tsx"; import { isDevMode } from "@/utils/isDevMode.ts"; import * as Contract from "@/hooks/contract/transferNFT"; +import lend from "@/hooks/contract/lend.ts"; import useTonConnect from "@/hooks/contract/useTonConnect.ts"; import { toNano, Address } from "@ton/core"; import { useLoanDetail } from "@/hooks/api/loan/useLoanDetail.tsx"; @@ -35,7 +36,7 @@ const BorrowVerify = () => { const navigate = useNavigate(); const { id } = useParams(); const location = useLocation(); - const { sendWithData } = Contract.transferNft(id); + const contract = Contract.transferNft(id); const { address } = useTonConnect(); const { borrowAmount } = location.state || {}; const { data: loanInfo } = useLoanDetail(Number(id), address, "pre"); @@ -49,7 +50,10 @@ const BorrowVerify = () => { { items: [ { label: "Borrowed NxTON", value: `${limitDecimals(loanInfo?.nxTonAmount, 3)} NxTON` }, - { label: "Principal", value: `${limitDecimals(loanInfo?.principal, 3)} ${nftDetail&&nftDetail[0].tokenSort=="nxTON"?"NxTON":nftDetail&&nftDetail[0].tokenSort}` }, + { + label: "Principal", + value: `${limitDecimals(loanInfo?.principal, 3)} ${nftDetail && nftDetail[0].tokenSort == "nxTON" ? "NxTON" : nftDetail && nftDetail[0].tokenSort}`, + }, { label: "LTV", value: `${limitDecimals(loanInfo?.loanToValue * 100, 2)}%` }, ], }, @@ -85,30 +89,20 @@ const BorrowVerify = () => { setIsLoading(true); try { - const data = () => { - return { - queryId: BigInt(Date.now()), - value: toNano("0.102"), - newOwner: Address.parse(import.meta.env.VITE_LEND_CONTRACT), - responseAddress: Address.parse(address), - fwdAmount: toNano("0.052"), - }; - }; - - await sendWithData(data(), toNano("0.05")); + await lend(Number(id), contract, Address.parse(address)); + let timeRotate = 0; while (true) { const response = await axios.get(`/data/validate-lending?nftId=${Number(id)}`, { baseURL: `${import.meta.env.VITE_BASE_URL}`, }); const validation = response.status; - if (validation && validation == 200 && timeRotate <= 24) { - break; - }else if (validation && validation == 202 && timeRotate <= 24){ - } - else{ + if (validation && validation == 200 && timeRotate <= 24) { break; - }; + } else if (validation && validation == 202 && timeRotate <= 24) { + } else { + break; + } timeRotate += 1; await delay(5000); } @@ -129,7 +123,7 @@ const BorrowVerify = () => { } finally { setIsLoading(false); } - }, [sendWithData, setError, borrowAmount, telegramId, address, id]); + }, [contract, setError, borrowAmount, telegramId, address, id]); const handleBorrowConfirm = () => { toggleModal(); diff --git a/src/pages/Loan/Repay/RepaymentDetails.tsx b/src/pages/Loan/Repay/RepaymentDetails.tsx index 9e6e4a1a..e5ea6281 100644 --- a/src/pages/Loan/Repay/RepaymentDetails.tsx +++ b/src/pages/Loan/Repay/RepaymentDetails.tsx @@ -53,7 +53,10 @@ const RepaymentDetails = () => { const alwaysVisibleItems = [ { label: "Borrowed NxTON", value: `${limitDecimals(borrowDetail?.repayAmount, 3)} NxTON` }, - { label: "Principal", value: `${limitDecimals(borrowDetail?.principal, 3)} ${nftDetail&&nftDetail[0]?.tokenSort=="nxTON"?"NxTON":nftDetail&&nftDetail[0]?.tokenSort}` }, + { + label: "Principal", + value: `${limitDecimals(borrowDetail?.principal, 3)} ${nftDetail && nftDetail[0]?.tokenSort == "nxTON" ? "NxTON" : nftDetail && nftDetail[0]?.tokenSort}`, + }, { label: "LTV", value: `${limitDecimals(borrowDetail?.loanToValue * 100, 2)}%` }, { label: "Interest rate", value: `${limitDecimals(borrowDetail?.interestRate * 100, 2)}%` }, ]; @@ -139,12 +142,11 @@ const RepaymentDetails = () => { const validation = response.status; console.log("test:", validation); if (validation && validation == 200 && timeRotate <= 24) { - break; - }else if (validation && validation == 202 && timeRotate <= 24){ - } - else{ break; - }; + } else if (validation && validation == 202 && timeRotate <= 24) { + } else { + break; + } timeRotate += 1; await delay(5000); } diff --git a/src/pages/MyAsset/NFTDetail/NFTDetail.tsx b/src/pages/MyAsset/NFTDetail/NFTDetail.tsx index d48f8f64..41d05196 100644 --- a/src/pages/MyAsset/NFTDetail/NFTDetail.tsx +++ b/src/pages/MyAsset/NFTDetail/NFTDetail.tsx @@ -32,13 +32,13 @@ import useTonConnect from "@/hooks/contract/useTonConnect"; const tele = (window as any).Telegram.WebApp; interface ModalState { - type: "blockborrow" | "blockunstake"|"blockborrow100"; + type: "blockborrow" | "blockunstake" | "blockborrow100"; toggled: boolean; } const NFTDetail = () => { const navigate = useNavigate(); - const location=useLocation(); + const location = useLocation(); const [nftInfo, setNftInfo] = useState(); const [stakingInfo, setStakingInfo] = useState([{ items: [] }]); const [isNftExpired, setIsNftExpired] = useState(false); @@ -111,17 +111,10 @@ const NFTDetail = () => { Staking NFT { - if(Number(id)<=100){ - setModal({type:"blockborrow100",toggled:true}); - }else if(!id||!address){ - setModal({type:"blockborrow100",toggled:true}); - } - else{ + onClick={() => { checkLendingAvailable?.success ? navigate(`/loan/${id}/borrow/details`) : setModal({ type: "blockborrow", toggled: true }); - } }} > Borrow NxTON trend_up @@ -148,7 +141,7 @@ const NFTDetail = () => { Token tonSymbol - {nftInfo?.tokenSort=="nxTON"?"NxTON":`${nftInfo?.tokenSort}`} + {nftInfo?.tokenSort == "nxTON" ? "NxTON" : `${nftInfo?.tokenSort}`} @@ -160,9 +153,15 @@ const NFTDetail = () => { - {modal.type==="blockborrow100"&&modal.toggled&&} - {modal.type === "blockborrow" && modal.toggled && } - {modal.type === "blockunstake" && modal.toggled && } + {modal.type === "blockborrow100" && modal.toggled && ( + + )} + {modal.type === "blockborrow" && modal.toggled && ( + + )} + {modal.type === "blockunstake" && modal.toggled && ( + + )} ); };