Skip to content
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

Transaction history, Multihop & Expert mode togglers #45

Merged
merged 29 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
503798a
fix: pools - change wrap native to default native
damnnou Apr 4, 2024
9db1cfe
add: multihop toggler to swap settings
damnnou Apr 4, 2024
eb1b57e
fix: add auto-refetch positions
damnnou Apr 4, 2024
3bfe873
add: user state storage save
damnnou Apr 5, 2024
d48831d
fix: remove partialize user state
damnnou Apr 5, 2024
e9db6fb
Merge pull request #33 from cryptoalgebra/fix/positions-refetch
lilchizh Apr 5, 2024
7d3848d
Merge pull request #28 from cryptoalgebra/feature/swap-multihop-toggler
lilchizh Apr 5, 2024
42d4278
Merge pull request #27 from cryptoalgebra/fix/table-pools
lilchizh Apr 5, 2024
bce7cbe
add: pending tx in header
damnnou Apr 5, 2024
7f462f2
fix: add wait for tx receipt, update max txs to 8
damnnou Apr 6, 2024
0e80d93
fix: add currencies logo + title to pending tx
damnnou Apr 8, 2024
bb46e3d
fix: link pending txs to selected account, refactor user store
damnnou Apr 8, 2024
930ab75
fix: save txs, update addresses
damnnou Apr 11, 2024
cfb2a4b
fix: prev addresses, hover tx card
damnnou Apr 11, 2024
bc1ef43
Merge pull request #34 from cryptoalgebra/feature/tx-history
lilchizh Apr 11, 2024
0df89a1
refactor: rename useTransitionAwait, add tx types, bring out farm img
damnnou Apr 12, 2024
4b1d5da
fix: remove exit farming button after remove liquidity
damnnou Apr 15, 2024
2248dbc
refactor: fix button repeat
damnnou Apr 15, 2024
f92e18d
fix: style fix farm modal
damnnou Apr 16, 2024
ab55ee7
fix: format currency title in swap and approve
damnnou Apr 17, 2024
85aa237
Merge pull request #37 from cryptoalgebra/feature/tx-history
lilchizh Apr 17, 2024
8374ba7
refactor: remove excess refetch, add key to btns
damnnou Apr 17, 2024
a2a2e0d
Merge branch 'dev' into fix/positions-refetch
lilchizh Apr 17, 2024
bb73df1
Merge pull request #38 from cryptoalgebra/fix/positions-refetch
lilchizh Apr 17, 2024
19f31ab
fix: useTransactionAwait import
damnnou Apr 17, 2024
64ad8ba
Merge pull request #39 from cryptoalgebra/fix/imports
lilchizh Apr 17, 2024
42bd3bd
(fix) Trade fee
lilchizh May 14, 2024
b3c9966
Merge pull request #41 from cryptoalgebra/fix/trade-fee
lilchizh May 14, 2024
5a1c9f9
fix: build ts error
damnnou May 22, 2024
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
4 changes: 4 additions & 0 deletions src/assets/etherscan-logo-circle-light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/assets/etherscan-logo-circle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
78 changes: 61 additions & 17 deletions src/components/common/Header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@ import { NavLink } from "react-router-dom"
import { useWeb3Modal, useWeb3ModalState } from "@web3modal/wagmi/react"
import { DEFAULT_CHAIN_ID, DEFAULT_CHAIN_NAME } from "@/constants/default-chain-id"
import { Button } from "@/components/ui/button"
import { UnplugIcon, WalletIcon } from "lucide-react"
import { AlignJustify, UnplugIcon, WalletIcon } from "lucide-react"
import Loader from "../Loader"
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
import { useState } from "react"
import { Address } from "viem"
import { TransactionCard } from "../TransactionCard"
import { useAccount } from "wagmi"
import { usePendingTransactions, usePendingTransactionsStore } from "@/state/pendingTransactionsStore"

const Header = () => <header className="sticky top-4 z-10 grid grid-cols-3 justify-between items-center py-1 px-2 bg-card border border-card-border rounded-3xl gap-4">
<Algebra />
Expand All @@ -28,6 +35,14 @@ const Account = () => {

const { open } = useWeb3Modal()

const { pendingTransactions } = usePendingTransactionsStore()

const { address: account } = useAccount();

const showTxHistory = account && pendingTransactions[account] ? Object.keys(pendingTransactions[account]).length > 0 : false

const pendingTxCount = account && pendingTransactions[account] ? Object.entries(pendingTransactions[account]).filter(([, transaction]) => transaction.loading).length : 0;

const { selectedNetworkId } = useWeb3ModalState()

if (selectedNetworkId !== DEFAULT_CHAIN_ID) return <div className="flex justify-end">
Expand All @@ -41,33 +56,62 @@ const Account = () => {
</Button>
</div>

return <div className="flex justify-end gap-4 pt-[2px] whitespace-nowrap">
return <div className="flex h-full justify-end gap-4 whitespace-nowrap">
<div className="hidden lg:block">
<w3m-network-button />
</div>
<div className="hidden md:block">
<w3m-button />
</div>
<div className="hidden md:block">
<w3m-button balance={pendingTxCount > 0 ? "hide" : "show"} />
</div>
<div className="md:hidden">
<Button onClick={() => open()} variant={'icon'} size={'icon'}>
<WalletIcon />
</Button>
</div>
{
showTxHistory &&
<TransactionHistoryPopover>
{
pendingTxCount > 0 ?
<Button
className="flex font-normal items-center my-auto h-10 px-3 justify-center gap-2 cursor-pointer hover:bg-primary-button/80 border border-card bg-primary-button rounded-3xl transition-all duration-200"
aria-label="Transaction history"
>
<Loader />
<span>{pendingTxCount}</span>
<span>Pending</span>
</Button>
:
<Button
variant="ghost"
className="flex font-normal items-center my-auto h-10 px-3 justify-center gap-2 bg-card-light/20 cursor-pointer border border-card-light hover:border-border/30 rounded-3xl transition-all duration-200"
aria-label="Transaction history"
>
<AlignJustify size={20} />
</Button>
}
</TransactionHistoryPopover>
}
</div>
}

// const Transactions = () => {
const TransactionHistoryPopover = ({children}: {children: React.ReactNode}) => {
const [isOpen, setIsOpen] = useState<boolean>(false);
const pendingTransactions = usePendingTransactions();
const { address: account } = useAccount();

// const [pendingTransactions, setPendingTransactions] = useState<OnTransactionsParameter>([])

// useWatchPendingTransactions({
// listener: (hashes) => setPendingTransactions(hashes)
// })

// return <Avatar className="w-[35px] h-[35px]">
// <AvatarFallback>{pendingTransactions.length}</AvatarFallback>
// </Avatar>

// }
if (account) return <Popover open={isOpen} onOpenChange={setIsOpen}>
<PopoverTrigger>
{children}
</PopoverTrigger>
<PopoverContent className="w-fit max-h-80 flex flex-col gap-4 -translate-x-28 translate-y-2 max-xl:-translate-x-8 max-xs:-translate-x-4" sideOffset={6}>
Transaction History
<hr/>
<ul className="flex flex-col gap-4 w-64 overflow-auto ">
{Object.entries(pendingTransactions[account]).reverse().map(([hash, transaction]) => <TransactionCard key={hash} hash={hash as Address} transaction={transaction} />)}
</ul>
</PopoverContent>
</Popover>
}

export default Header
4 changes: 3 additions & 1 deletion src/components/common/Loader/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { cn } from "@/lib/utils";
import { Loader2Icon } from "lucide-react";

interface LoaderProps {
size?: number;
color?: string;
className?: string;
}

const Loader = ({ size = 22, color = 'white' }: LoaderProps) => <Loader2Icon size={size} color={color} className="animate-spin" />
const Loader = ({ size = 22, color = 'white', className }: LoaderProps) => <Loader2Icon size={size} color={color} className={cn("animate-spin", className)} />

export default Loader
21 changes: 18 additions & 3 deletions src/components/common/Settings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ const Settings = () => {
<SettingsIcon />
</Button>
</PopoverTrigger>
<PopoverContent align={'end'} className="flex flex-col gap-4 w-fit bg-card rounded-3xl border border-card-border text-white">
<PopoverContent align={'end'} className="flex flex-col gap-4 p-6 w-fit bg-card rounded-3xl border border-card-border text-white">
<div className="text-md font-bold">Transaction Settings</div>
<Separator orientation={'horizontal'} className="bg-border" />
<SlippageTolerance />
<TransactionDeadline />
<Multihop />
<ExpertMode />
</PopoverContent>
</Popover>
Expand Down Expand Up @@ -156,13 +157,27 @@ const ExpertMode = () => {

return <div className="flex flex-col gap-2 max-w-[332px]">
<div className="flex justify-between items-center gap-2 text-md font-semibold">
Expert Mode
<Switch checked={isExpertMode} onCheckedChange={setIsExpertMode} />
<label htmlFor="expert-mode">Expert mode</label>
<Switch id="expert-mode" checked={isExpertMode} onCheckedChange={setIsExpertMode} />
</div>
<p className="whitespace-break-spaces">
Advanced control over swap parameters such as price setting and gas management.
</p>
</div>
}

const Multihop = () => {
const { isMultihop, actions: { setIsMultihop } } = useUserState();

return <div className="flex flex-col gap-2 max-w-[332px]">
<div className="flex justify-between items-center gap-2 text-md font-semibold">
<label htmlFor="multihop">Multihop</label>
<Switch id="multihop" checked={isMultihop} onCheckedChange={setIsMultihop} />
</div>
<p className="whitespace-break-spaces">
Optimized trades across multiple liquidity pools.
</p>
</div>
}

export default Settings;
9 changes: 6 additions & 3 deletions src/components/common/Table/poolsColumns.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { ColumnDef } from '@tanstack/react-table';
import { HeaderItem } from './common';
import { Address } from 'wagmi';
import { useCurrency } from '@/hooks/common/useCurrency';
import CurrencyLogo from '../CurrencyLogo';
import { TokenFieldsFragment } from '@/graphql/generated/graphql';
import { DynamicFeePluginIcon } from '../PluginIcons';
import { formatUSD } from '@/utils/common/formatUSD';
import { usePoolPlugins } from '@/hooks/pools/usePoolPlugins';
import { Skeleton } from '@/components/ui/skeleton';
import { FarmingPluginIcon } from '../PluginIcons';
import { useCurrency } from '@/hooks/common/useCurrency';

interface Pair {
token0: TokenFieldsFragment;
Expand All @@ -26,8 +26,11 @@ interface Pool {
}

const PoolPair = ({ pair, fee }: Pool) => {
const currencyA = useCurrency(pair.token0.id as Address);
const currencyB = useCurrency(pair.token1.id as Address);
const token0 = pair.token0.id as Address;
const token1 = pair.token1.id as Address;

const currencyA = useCurrency(token0, true);
const currencyB = useCurrency(token1, true);

return (
<div className="flex items-center gap-4 ml-2">
Expand Down
62 changes: 62 additions & 0 deletions src/components/common/TransactionCard/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { useCurrency } from "@/hooks/common/useCurrency";
import { truncateHash } from "@/utils/common/truncateHash";
import { Address } from "viem";
import CurrencyLogo from "../CurrencyLogo";
import EtherScanLogo from "@/assets/etherscan-logo-circle.svg"
import { Check, ExternalLinkIcon, X } from "lucide-react";
import { Link } from "react-router-dom";
import { Transaction, TransactionType } from "@/state/pendingTransactionsStore";
import Loader from "../Loader";
import { FarmingPositionImg } from "@/components/farming/FarmingPositionImg";

export const TransactionCard = ({ hash, transaction }: { hash: Address, transaction: Transaction }) => {
const currencyA = useCurrency(transaction.data.tokenA, true);
const currencyB = useCurrency(transaction.data.tokenB, true);

const txType = transaction.data.type;

return <Link
to={`https://holesky.etherscan.io/tx/${hash}`}
target={'_blank'}
>
<li className="flex group h-16 justify-between items-center gap-4 w-full bg-card-dark rounded-3xl p-4 border border-border/60 hover:border-border hover:bg-card-dark/60 transition-all duration-200" key={hash}>
{
txType === TransactionType.FARM && transaction.data.tokenId ?
<FarmingPositionImg positionId={BigInt(transaction.data.tokenId)} size={10} />
:

currencyB && currencyA ?
<div className="w-[36px] relative">
<CurrencyLogo className="absolute bottom-0 translate-y-1/4" currency={currencyA} size={28} />
<CurrencyLogo className="absolute top-0 left-3 -translate-y-1/4" currency={currencyB} size={28} />
</div>
:
currencyA ?
<CurrencyLogo currency={currencyA} size={40} />
:
<img className="brightness-150" src={EtherScanLogo} width={40} height={40} />

}
<div className="flex flex-col mr-auto">
<span className="text-xs opacity-60">{transaction.data.title}</span>
{
currencyB && currencyA ?
<span className="text-sm">{currencyA.symbol} / {currencyB.symbol}</span>
:
currencyA ?
<span className="text-sm">{currencyA.symbol}</span>
:
<span>{truncateHash(hash as Address)}</span>
}
</div>
{
transaction.loading ? <Loader className="group-hover:hidden" size={20} />
:
transaction.success ? <Check className="text-blue-300 group-hover:hidden" size={18} />
:
transaction.error && <X className="text-red-500 group-hover:hidden" size={18} />
}
<ExternalLinkIcon className="hidden group-hover:block" size={18} />
</li>
</Link>
}
13 changes: 9 additions & 4 deletions src/components/create-pool/CreatePoolForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ import {
computePoolAddress,
} from '@cryptoalgebra/integral-sdk';
import { usePrepareAlgebraPositionManagerMulticall } from '@/generated';
import { useTransitionAwait } from '@/hooks/common/useTransactionAwait';
import { useTransactionAwait } from '@/hooks/common/useTransactionAwait';
import { Address, useContractWrite } from 'wagmi';
import { useDerivedMintInfo, useMintState } from '@/state/mintStore';
import Loader from '@/components/common/Loader';
import { PoolState, usePool } from '@/hooks/pools/usePool';
import Summary from '../Summary';
import SelectPair from '../SelectPair';
import { STABLECOINS } from '@/constants/tokens';
import { TransactionType } from '@/state/pendingTransactionsStore';

const CreatePoolForm = () => {
const { currencies } = useDerivedSwapInfo();
Expand Down Expand Up @@ -77,10 +78,14 @@ const CreatePoolForm = () => {
const { data: createPoolData, write: createPool } =
useContractWrite(createPoolConfig);

const { isLoading } = useTransitionAwait(
const { isLoading } = useTransactionAwait(
createPoolData?.hash,
'Create Pool',
'',
{
title: 'Create Pool',
tokenA: currencyA?.wrapped.address as Address,
tokenB: currencyB?.wrapped.address as Address,
type: TransactionType.POOL,
},
'/pools'
);

Expand Down
13 changes: 9 additions & 4 deletions src/components/create-position/AddLiquidityButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import {
} from '@/constants/default-chain-id';
import { usePrepareAlgebraPositionManagerMulticall } from '@/generated';
import { useApprove } from '@/hooks/common/useApprove';
import { useTransitionAwait } from '@/hooks/common/useTransactionAwait';
import { useTransactionAwait } from '@/hooks/common/useTransactionAwait';
import { IDerivedMintInfo } from '@/state/mintStore';
import { TransactionType } from '@/state/pendingTransactionsStore';
import { useUserState } from '@/state/userStore';
import { ApprovalState } from '@/types/approve-state';
import {
Expand Down Expand Up @@ -118,10 +119,14 @@ export const AddLiquidityButton = ({
const { data: addLiquidityData, write: addLiquidity } =
useContractWrite(addLiquidityConfig);

const { isLoading: isAddingLiquidityLoading } = useTransitionAwait(
const { isLoading: isAddingLiquidityLoading } = useTransactionAwait(
addLiquidityData?.hash,
'Add liquidity',
'',
{
title: 'Add liquidity',
tokenA: baseCurrency?.wrapped.address as Address,
tokenB: quoteCurrency?.wrapped.address as Address,
type: TransactionType.POOL,
},
`/pool/${poolAddress}`
);

Expand Down
Loading
Loading