Skip to content

Commit

Permalink
feat: margin trading
Browse files Browse the repository at this point in the history
  • Loading branch information
deep-path committed Nov 25, 2024
1 parent aead6d3 commit 6bb1a56
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 36 deletions.
36 changes: 25 additions & 11 deletions components/HashResultModal/ModalWithClosePosition.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useEffect } from "react";
import React, { useState, useEffect, useRef } from "react";
import { NearIconMini } from "../../screens/MarginTrading/components/Icon";
import { CloseIcon } from "../Icons/Icons";

Expand All @@ -20,42 +20,56 @@ const ModalWithFailure = ({
const [isModalVisible, setIsModalVisible] = useState(false);
const [countdown, setCountdown] = useState(10);
const [progress, setProgress] = useState(100);
let countdownTimer;

// 使用 useRef 来存储 timer
const countdownTimerRef = useRef<NodeJS.Timeout | null>(null);

useEffect(() => {
if (show) {
setIsModalVisible(true);
startCountdown();
} else {
setIsModalVisible(false);
clearTimeoutOrInterval(countdownTimer);
// 使用 setTimeout 来延迟隐藏模态框
const hideTimeout = setTimeout(() => {
setIsModalVisible(false);
clearTimeoutOrInterval(countdownTimerRef.current);
}, 0);

return () => clearTimeout(hideTimeout);
}
return () => clearTimeoutOrInterval(countdownTimer);

return () => clearTimeoutOrInterval(countdownTimerRef.current);
}, [show]);

const clearTimeoutOrInterval = (timerId) => {
if (timerId) {
clearInterval(timerId);
countdownTimer = null;
countdownTimerRef.current = null;
}
};

const hideModal = () => {
setIsModalVisible(false);
onClose();
clearTimeout(countdownTimer);
// 使用 setTimeout 来避免同步卸载
setTimeout(() => {
setIsModalVisible(false);
onClose();
clearTimeoutOrInterval(countdownTimerRef.current);

const cleanUrl = window.location.href.split("?")[0];
window.history.replaceState({}, "", cleanUrl);
}, 0);
};

const startCountdown = () => {
setCountdown(10);
setProgress(100);

const timerInterval = 1000;
countdownTimer = setInterval(() => {
countdownTimerRef.current = setInterval(() => {
setCountdown((prevCountdown) => {
if (prevCountdown <= 1) {
hideModal();
clearTimeoutOrInterval(countdownTimer);
clearTimeoutOrInterval(countdownTimerRef.current);
return 0;
}
return prevCountdown - 1;
Expand Down
2 changes: 2 additions & 0 deletions components/HashResultModal/ModalWithCountdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ const ModalWithCountdown = ({
const hideModal = () => {
setIsModalVisible(false);
clearTimeout(countdownTimer);
const cleanUrl = window.location.href.split("?")[0];
window.history.replaceState({}, "", cleanUrl);
};

const startCountdown = () => {
Expand Down
2 changes: 2 additions & 0 deletions components/HashResultModal/ModalWithFailure.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ const ModalWithFailure = ({
setIsModalVisible(false);
onClose();
clearTimeout(countdownTimer);
const cleanUrl = window.location.href.split("?")[0];
window.history.replaceState({}, "", cleanUrl);
};

const startCountdown = () => {
Expand Down
5 changes: 4 additions & 1 deletion screens/Trading/components/ClosePositionMobile.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState, createContext } from "react";
import { useState, createContext, useEffect } from "react";
import { Modal as MUIModal, Box, useTheme } from "@mui/material";
import { BeatLoader } from "react-spinners";
import { useAppDispatch, useAppSelector } from "../../../redux/hooks";
Expand Down Expand Up @@ -89,6 +89,9 @@ const ClosePositionMobile = ({ open, onClose, extraProps }) => {
slippageTolerance: ReduxSlippageTolerance / 100,
});
// console.log(estimateData, "85>>>");
useEffect(() => {
setIsDisabled(!estimateData?.swap_indication || !estimateData?.min_amount_out);
}, [estimateData]);
const [isDisabled, setIsDisabled] = useState(false);
const handleCloseOpsitionEvt = async () => {
// console.log(extraProps, "extraProps....");
Expand Down
2 changes: 1 addition & 1 deletion screens/Trading/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ const Trading = () => {
};

useEffect(() => {
handleTransactionResults(query?.transactionHashes, query?.errorMessage);
if (query?.transactionHashes) {
(async () => {
const txHash = await handleTransactionHash(query?.transactionHashes);
Expand All @@ -162,6 +161,7 @@ const Trading = () => {
});
})();
}
handleTransactionResults(query?.transactionHashes, query?.errorMessage);
}, [query?.transactionHashes, query?.errorMessage]);

//
Expand Down
78 changes: 55 additions & 23 deletions services/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,34 +32,45 @@ export const handleTransactionResults = async (
}),
);

const shouldShowClose = results.some(({ result, hasStorageDeposit }: TransactionResult) => {
if (hasStorageDeposit) {
const args = parsedArgs(result?.transaction?.actions?.[0]?.FunctionCall?.args || "");
const { actions } = JSON.parse(args || "");
return actions[0]?.CloseMTPosition;
}
return false;
});

if (shouldShowClose) {
showPositionClose({});
return;
}

results.forEach(({ result, hasStorageDeposit }: TransactionResult) => {
if (hasStorageDeposit) {
const args = parsedArgs(result?.transaction?.actions?.[0]?.FunctionCall?.args || "");
const { actions } = JSON.parse(args || "");
console.log(actions, "actions....");
const isLong = actions[0]?.OpenPosition?.token_p_id == "wrap.testnet";

if (actions[0]?.CloseMTPosition) {
showPositionClose({});
} else {
showPositionResult({
title: "Open Position",
type: isLong ? "Long" : "Short",
price: (isLong
? Number(shrinkToken(actions[0]?.OpenPosition?.token_d_amount, 18)) /
Number(shrinkToken(actions[0]?.OpenPosition?.min_token_p_amount, 24))
: Number(shrinkToken(actions[0]?.OpenPosition?.min_token_p_amount, 18)) /
Number(shrinkToken(actions[0]?.OpenPosition?.token_d_amount, 24))
).toString(),
transactionHashes: txhash[0],
positionSize: {
amount: isLong
? shrinkToken(actions[0]?.OpenPosition?.min_token_p_amount, 24, 6)
: shrinkToken(actions[0]?.OpenPosition?.token_d_amount, 24, 6),
symbol: "NEAR",
usdValue: "1000",
},
});
}
showPositionResult({
title: "Open Position",
type: isLong ? "Long" : "Short",
price: (isLong
? Number(shrinkToken(actions[0]?.OpenPosition?.token_d_amount, 18)) /
Number(shrinkToken(actions[0]?.OpenPosition?.min_token_p_amount, 24))
: Number(shrinkToken(actions[0]?.OpenPosition?.min_token_p_amount, 18)) /
Number(shrinkToken(actions[0]?.OpenPosition?.token_d_amount, 24))
).toString(),
transactionHashes: txhash[0],
positionSize: {
amount: isLong
? shrinkToken(actions[0]?.OpenPosition?.min_token_p_amount, 24, 6)
: shrinkToken(actions[0]?.OpenPosition?.token_d_amount, 24, 6),
symbol: "NEAR",
usdValue: "1000",
},
});
}
});
} catch (error) {
Expand All @@ -77,6 +88,7 @@ export const handleTransactionResults = async (

export const handleTransactionHash = async (
transactionHashes: string | string[] | undefined,
errorMessage?: string | string[],
): Promise<TransactionResult[]> => {
if (transactionHashes) {
try {
Expand All @@ -87,13 +99,33 @@ export const handleTransactionHash = async (
const results = await Promise.all(
txhash.map(async (txHash: string): Promise<TransactionResult> => {
const result: any = await getTransactionResult(txHash);
const hasStorageDeposit = result.transaction.actions.some(
let hasStorageDeposit = false;

const isMarginExecute = result.transaction.actions.some(
(action: any) => action?.FunctionCall?.method_name === "margin_execute_with_pyth",
);

if (isMarginExecute) {
const args = parsedArgs(result?.transaction?.actions?.[0]?.FunctionCall?.args || "");
const { actions } = JSON.parse(args || "");
hasStorageDeposit = !actions[0]?.CloseMTPosition;
}

return { txHash, result, hasStorageDeposit };
}),
);

// 检查是否有任何一个交易的 hasStorageDeposit 为 false
const hasAnyFalseStorageDeposit = results.some((result) => !result.hasStorageDeposit);

// 如果有任何一个为 false,则所有结果的 hasStorageDeposit 都设为 false
if (hasAnyFalseStorageDeposit) {
return results.map((result) => ({
...result,
hasStorageDeposit: false,
}));
}

return results;
} catch (error) {
console.error("Error processing transactions:", error);
Expand Down

0 comments on commit 6bb1a56

Please sign in to comment.