Skip to content

Feat/og lending #52

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
33 changes: 33 additions & 0 deletions src/hooks/contract/lend.ts
Original file line number Diff line number Diff line change
@@ -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"),
);
}
}
7 changes: 5 additions & 2 deletions src/hooks/contract/repay.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -51,4 +54,4 @@ function repay(id) {
};
}

export { repay };
export { repay };
3 changes: 2 additions & 1 deletion src/hooks/contract/transferNFT.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ function transferNft(id) {
newOwner: data.newOwner,
responseAddress: data.responseAddress,
forwardAmount: data.fwdAmount,
forwardPayload: data.fwdPayload,
});
await sender.send({
to: nftAddress,
Expand All @@ -58,7 +59,7 @@ function transferNft(id) {
} else {
throw new Error("NftAddress not set");
}
} catch {
} catch (error) {
throw new Error("Error while sending nft");
}
},
Expand Down
58 changes: 29 additions & 29 deletions src/hooks/contract/wrappers/NftItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,43 +180,43 @@ 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, {
value: params.value,
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: {
Expand All @@ -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();
}
}
87 changes: 84 additions & 3 deletions src/pages/Dashboard/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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이 겹쳐서 변수명 설정해줌
Expand Down Expand Up @@ -81,7 +82,7 @@ const Dashboard = () => {
} = useBotPerformanceChart(chartTimeFrameOptions[timeFrame]);

const { data: tonPriceData, isLoading: tonPriceLoading, error: tonPriceError } = useCoinPrice("ton", "usd");

useEffect(() => {
if (tele) {
tele.ready();
Expand Down Expand Up @@ -177,12 +178,69 @@ const Dashboard = () => {
<h3>Stakers Win Rate</h3>
<p>{performanceData?.pnlWinRate?.toFixed(2)}%</p>
</PerformanceItem>
<PerformanceItem>
<ClickAwayListener onClickAway={handleTooltipClose}>
<PerformanceItem onClick={handleTooltip}>
<h3 style={{ display: "flex", alignItems: "center", gap: "6px" }}>
TVL
<MuiTooltip
PopperProps={{
disablePortal: true,
}}
onClose={handleTooltip}
open={open}
disableTouchListener
disableHoverListener // 추가
title={
<TooltipText>
<img src={IcTonLogo} /> TON+
<img src={IcnxTONLogo} />
nxTON
</TooltipText>
}
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
>
<div>
<VscInfo
style={{
width: "16px",
height: "16px",
color: "#C6CACA",
alignItems: "center",
justifyContent: "center",
display: "flex",
}}
/>
</div>
</MuiTooltip>
</h3>
<p>{limitDecimals(performanceData?.tvl, 3)} TON</p>
</PerformanceItem>
</ClickAwayListener>
</PerformanceItemWrapper>
<MainButton style={{ margin: "1.5rem 0 6.1rem 0" }} />

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

<TonPriceItemRight>
<p>${tonPriceData?.rates?.TON?.prices?.USD.toFixed(2)}</p>
<TonPriceItemRightPercentage $positive={(tonPriceData?.rates?.TON?.diff_24h?.USD[0])=="+"?true:false}>
<TonPriceItemRightPercentage
$positive={tonPriceData?.rates?.TON?.diff_24h?.USD[0] == "+" ? true : false}
>
{tonPriceData?.rates?.TON?.diff_24h?.USD}
</TonPriceItemRightPercentage>
</TonPriceItemRight>
Expand All @@ -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;
}
`;
34 changes: 14 additions & 20 deletions src/pages/Loan/Borrow/BorrowVerify.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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");
Expand All @@ -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)}%` },
],
},
Expand Down Expand Up @@ -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);
}
Expand All @@ -129,7 +123,7 @@ const BorrowVerify = () => {
} finally {
setIsLoading(false);
}
}, [sendWithData, setError, borrowAmount, telegramId, address, id]);
}, [contract, setError, borrowAmount, telegramId, address, id]);

const handleBorrowConfirm = () => {
toggleModal();
Expand Down
14 changes: 8 additions & 6 deletions src/pages/Loan/Repay/RepaymentDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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)}%` },
];
Expand Down Expand Up @@ -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);
}
Expand Down
Loading