Skip to content

Commit

Permalink
Merge pull request #935 from mrgnlabs/feature/improved-transactions
Browse files Browse the repository at this point in the history
feat(mfi-v2-ui): improved transactions
  • Loading branch information
k0beLeenders authored Oct 31, 2024
2 parents 7aff68c + 977ab08 commit 5cfb2c7
Show file tree
Hide file tree
Showing 53 changed files with 1,653 additions and 551 deletions.
35 changes: 30 additions & 5 deletions apps/marginfi-v2-trading/src/components/common/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,26 @@ import React from "react";
import Link from "next/link";
import { useRouter } from "next/router";
import { motion, useAnimate } from "framer-motion";
import { IconPlus, IconCopy, IconCheck } from "@tabler/icons-react";
import { IconPlus, IconCopy, IconCheck, IconSettings } from "@tabler/icons-react";
import { CopyToClipboard } from "react-copy-to-clipboard";
import { cn } from "@mrgnlabs/mrgn-utils";
import { USDC_MINT } from "@mrgnlabs/mrgn-common";
import { Settings } from "@mrgnlabs/mrgn-ui";

import { useTradeStore } from "~/store";
import { useTradeStore, useUiStore } from "~/store";
import { useWallet } from "~/components/wallet-v2/hooks/use-wallet.hook";
import { useIsMobile } from "~/hooks/use-is-mobile";
import { useConnection } from "~/hooks/use-connection";

import { Wallet } from "~/components/wallet-v2";
import { CreatePoolScriptDialog } from "../Pool/CreatePoolScript";
import { CreatePoolSoon } from "../Pool/CreatePoolSoon";
import { CreatePoolDialog } from "../Pool/CreatePoolDialog";
import { Button } from "~/components/ui/button";
import { IconArena } from "~/components/ui/icons";
import { Popover, PopoverContent, PopoverTrigger } from "~/components/ui/popover";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "~/components/ui/tooltip";

import { CreatePoolScriptDialog } from "../Pool/CreatePoolScript";
import { CreatePoolSoon } from "../Pool/CreatePoolSoon";

const navItems = [
{ label: "Discover", href: "/" },
{ label: "Yield", href: "/yield" },
Expand All @@ -41,6 +43,13 @@ export const Header = () => {
state.referralCode,
]
);
const { priorityType, broadcastType, maxCap, maxCapType, setTransactionSettings } = useUiStore((state) => ({
priorityType: state.priorityType,
broadcastType: state.broadcastType,
maxCap: state.maxCap,
maxCapType: state.maxCapType,
setTransactionSettings: state.setTransactionSettings,
}));
const { wallet } = useWallet();
const { asPath } = useRouter();
const isMobile = useIsMobile();
Expand Down Expand Up @@ -140,6 +149,22 @@ export const Header = () => {
/> */}
</div>
)}
<Popover>
<PopoverTrigger asChild>
<Button variant="ghost" size="icon" className="h-10 w-10 shrink-0">
<IconSettings size={20} />
</Button>
</PopoverTrigger>
<PopoverContent className="w-80">
<Settings
onChange={setTransactionSettings}
broadcastType={broadcastType}
priorityType={priorityType}
maxCap={maxCap}
maxCapType={maxCapType}
/>
</PopoverContent>
</Popover>
<Wallet
connection={connection}
initialized={initialized}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,6 @@ export const CreatePoolLoading = ({ quoteBank, poolData, setPoolData, setCreateP
const { wallet } = useWallet();
const { connection } = useConnection();
const [fetchTradeState] = useTradeStore((state) => [state.fetchTradeState]);
const [priorityFee] = useUiStore((state) => [state.priorityFee]);
const [activeStep, setActiveStep] = React.useState<number>(0);
const [status, setStatus] = React.useState<StepperStatus>("default");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ type PoolCreationState = {
export const CreatePoolLoading = ({ poolCreatedData, setIsOpen, setIsCompleted }: CreatePoolLoadingProps) => {
// const { wallet } = useWallet();
const { connection } = useConnection();
const [priorityFee] = useUiStore((state) => [state.priorityFee]);
const [activeStep, setActiveStep] = React.useState<number>(0);
const [status, setStatus] = React.useState<StepperStatus>("default");

Expand Down Expand Up @@ -208,7 +207,7 @@ export const CreatePoolLoading = ({ poolCreatedData, setIsOpen, setIsCompleted }
group,
admin: wallet.publicKey,
seed,
priorityFee,
priorityFee: 0, // todo
});

if (!sig) throw new Error();
Expand All @@ -218,7 +217,7 @@ export const CreatePoolLoading = ({ poolCreatedData, setIsOpen, setIsCompleted }
setStatus("error");
}
},
[priorityFee, setStatus]
[setStatus]
);

const createSeeds = React.useCallback(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Image from "next/image";
import { IconMinus, IconX, IconPlus, IconLoader2 } from "@tabler/icons-react";
import { Transaction, VersionedTransaction } from "@solana/web3.js";

import { MultiStepToastHandle, cn, extractErrorString, capture } from "@mrgnlabs/mrgn-utils";
import { MultiStepToastHandle, cn, extractErrorString, capture, fetchPriorityFee } from "@mrgnlabs/mrgn-utils";
import { ActiveBankInfo, ActionType } from "@mrgnlabs/marginfi-v2-ui-state";

import { useConnection } from "~/hooks/use-connection";
Expand Down Expand Up @@ -56,12 +56,16 @@ export const PositionActionButtons = ({
state.setIsRefreshingStore,
state.nativeSolBalance,
]);
const [slippageBps, priorityFee, setIsActionComplete, setPreviousTxn] = useUiStore((state) => [
state.slippageBps,
state.priorityFee,
state.setIsActionComplete,
state.setPreviousTxn,
]);
const [slippageBps, priorityType, broadcastType, maxCap, maxCapType, setIsActionComplete, setPreviousTxn] =
useUiStore((state) => [
state.slippageBps,
state.priorityType,
state.broadcastType,
state.maxCap,
state.maxCapType,
state.setIsActionComplete,
state.setPreviousTxn,
]);

const depositBanks = React.useMemo(() => {
const tokenBank = activeGroup.pool.token.isActive ? activeGroup.pool.token : null;
Expand Down Expand Up @@ -103,13 +107,15 @@ export const PositionActionButtons = ({
throw new Error("Invalid client");
}

const priorityFeeUi = await fetchPriorityFee(maxCapType, maxCap, broadcastType, priorityType, connection);

const txns = await calculateClosePositions({
marginfiAccount: activeGroup.selectedAccount,
depositBanks: depositBanks,
borrowBank: borrowBank,
slippageBps,
connection: connection,
priorityFee,
priorityFee: priorityFeeUi,
platformFeeBps,
});

Expand All @@ -128,7 +134,18 @@ export const PositionActionButtons = ({
setMultiStepToast(multiStepToast);
}
setIsClosing(false);
}, [activeGroup, slippageBps, connection, priorityFee, platformFeeBps, borrowBank, depositBanks, setIsClosing]);
}, [
activeGroup,
borrowBank,
depositBanks,
maxCapType,
maxCap,
broadcastType,
priorityType,
connection,
slippageBps,
platformFeeBps,
]);

const processTransaction = React.useCallback(async () => {
try {
Expand All @@ -140,10 +157,13 @@ export const PositionActionButtons = ({
txnSig = await activeGroup.client.processTransaction(actionTransaction.closeTxn);
multiStepToast.setSuccessAndNext();
} else {
txnSig = await activeGroup.client.processTransactions([
...actionTransaction.feedCrankTxs,
actionTransaction.closeTxn,
]);
txnSig = await activeGroup.client.processTransactions(
[...actionTransaction.feedCrankTxs, actionTransaction.closeTxn],
undefined,
undefined,
broadcastType,
true
);
multiStepToast.setSuccessAndNext();
}

Expand Down Expand Up @@ -202,6 +222,7 @@ export const PositionActionButtons = ({
connection,
setIsActionComplete,
setPreviousTxn,
broadcastType,
]);

const onClose = React.useCallback(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
capture,
extractErrorString,
usePrevious,
usePriorityFee,
} from "@mrgnlabs/mrgn-utils";
import { MarginfiAccountWrapper, SimulationResult, computeMaxLeverage } from "@mrgnlabs/marginfi-client-v2";
import { IconAlertTriangle, IconExternalLink, IconLoader2, IconSettings, IconWallet } from "@tabler/icons-react";
Expand Down Expand Up @@ -75,16 +76,29 @@ export const TradingBox = ({ activeGroup, side = "long" }: TradingBoxProps) => {
state.refreshGroup,
]);

const [slippageBps, priorityFee, platformFeeBps, setSlippageBps, setIsActionComplete, setPreviousTxn] = useUiStore(
(state) => [
state.slippageBps,
state.priorityFee,
state.platformFeeBps,
state.setSlippageBps,
state.setIsActionComplete,
state.setPreviousTxn,
]
);
const [
slippageBps,
platformFeeBps,
priorityType,
broadcastType,
maxCap,
maxCapType,
setSlippageBps,
setIsActionComplete,
setPreviousTxn,
] = useUiStore((state) => [
state.slippageBps,
state.platformFeeBps,
state.priorityType,
state.broadcastType,
state.maxCap,
state.maxCapType,
state.setSlippageBps,
state.setIsActionComplete,
state.setPreviousTxn,
]);

const priorityFee = usePriorityFee(priorityType, broadcastType, maxCapType, maxCap, connection);

const [setIsWalletOpen] = useWalletStore((state) => [state.setIsWalletOpen]);

Expand Down Expand Up @@ -236,6 +250,7 @@ export const TradingBox = ({ activeGroup, side = "long" }: TradingBoxProps) => {
connection,
platformFeeBps,
isTrading: true,
broadcastType: broadcastType,
});

let loopingObject: LoopingObject | null = null;
Expand Down Expand Up @@ -263,10 +278,11 @@ export const TradingBox = ({ activeGroup, side = "long" }: TradingBoxProps) => {
amount,
leverage,
tradeState,
slippageBps,
priorityFee,
slippageBps,
connection,
platformFeeBps,
broadcastType,
handleSimulation,
]);

Expand Down Expand Up @@ -298,12 +314,23 @@ export const TradingBox = ({ activeGroup, side = "long" }: TradingBoxProps) => {
loopingObject,
priorityFee,
slippageBps: slippageBps,
broadcastType: broadcastType,
connection,
});

return sig;
},
[amount, connection, loopingObject, priorityFee, activeGroup, slippageBps, tradeState, walletContextState]
[
amount,
connection,
loopingObject,
priorityFee,
activeGroup,
slippageBps,
tradeState,
broadcastType,
walletContextState,
]
);

const handleLeverageAction = React.useCallback(async () => {
Expand Down Expand Up @@ -547,24 +574,26 @@ export const TradingBox = ({ activeGroup, side = "long" }: TradingBoxProps) => {
</div>
</div>
)}
{connected && tradeState === "short" && activeGroup?.pool.quoteTokens[0].userInfo.tokenAccount.balance === 0 && (
<div className="w-full flex space-x-2 py-2.5 px-3.5 rounded-lg gap-1 text-sm bg-accent text-alert-foreground">
<IconAlertTriangle className="shrink-0 translate-y-0.5" size={16} />
<div className="space-y-1">
<p>
You need to hold {activeGroup?.pool.quoteTokens[0].meta.tokenSymbol} to open a short position.{" "}
<button
className="border-b border-alert-foreground hover:border-transparent"
onClick={() => {
setIsWalletOpen(true);
}}
>
Swap tokens.
</button>
</p>
{connected &&
tradeState === "short" &&
activeGroup?.pool.quoteTokens[0].userInfo.tokenAccount.balance === 0 && (
<div className="w-full flex space-x-2 py-2.5 px-3.5 rounded-lg gap-1 text-sm bg-accent text-alert-foreground">
<IconAlertTriangle className="shrink-0 translate-y-0.5" size={16} />
<div className="space-y-1">
<p>
You need to hold {activeGroup?.pool.quoteTokens[0].meta.tokenSymbol} to open a short position.{" "}
<button
className="border-b border-alert-foreground hover:border-transparent"
onClick={() => {
setIsWalletOpen(true);
}}
>
Swap tokens.
</button>
</p>
</div>
</div>
</div>
)}
)}
{isActiveWithCollat ? (
<>
<div className="gap-1 w-full flex flex-col items-center">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from "react";
import { IconArrowLeft } from "@tabler/icons-react";

import { ToggleGroup, ToggleGroupItem } from "~/components/ui/toggle-group";
import { Slippage, PriorityFees } from "./components";
import { Slippage } from "./components";

type TradingBoxSettingsProps = {
toggleSettings: (mode: boolean) => void;
Expand All @@ -30,7 +30,7 @@ export const TradingBoxSettings = ({ toggleSettings, slippageBps, setSlippageBps
<button className="flex items-center gap-1.5 text-sm" onClick={() => toggleSettings(false)}>
<IconArrowLeft size={18} /> Back to trading
</button>
<div className="space-y-3">
{/* <div className="space-y-3">
<ToggleGroup value={settingsMode} onValueChange={toggleSettingsMode} type="single" size="lg" className="gap-4">
<ToggleGroupItem value="slippage" className="w-1/2 text-xs border">
Slippage
Expand All @@ -40,12 +40,11 @@ export const TradingBoxSettings = ({ toggleSettings, slippageBps, setSlippageBps
Priority Fee
</ToggleGroupItem>
</ToggleGroup>
</div>
</div> */}
<div>
{settingsMode === SettingsState.Slippage && (
<Slippage toggleSettings={toggleSettings} slippageBps={slippageBps} setSlippageBps={setSlippageBps} />
)}
{settingsMode === SettingsState.PriorityFee && <PriorityFees toggleSettings={toggleSettings} />}
</div>
</div>
);
Expand Down
Loading

0 comments on commit 5cfb2c7

Please sign in to comment.