Skip to content

Commit

Permalink
display swap2 in transaction history, along with token icons
Browse files Browse the repository at this point in the history
  • Loading branch information
eli-d committed Jan 20, 2025
1 parent 9331621 commit a69458f
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 23 deletions.
7 changes: 5 additions & 2 deletions web/src/app/_DataTable/columns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Badge } from "@/components/ui/badge";
import Token from "@/assets/icons/token.svg";
import { usdFormat } from "@/lib/usdFormat";
import { useSwapStore } from "@/stores/useSwapStore";
import { TokenIcon } from "@/components/TokenIcon";

export type Transaction = {
id: string;
Expand All @@ -14,6 +15,8 @@ export type Transaction = {
time: Date;
amountFrom: number;
amountTo: number;
iconFrom: string;
iconTo: string;
};

const AmountHeader = () => {
Expand All @@ -38,7 +41,7 @@ export const columns: (ColumnDef<Transaction> & { colSpan?: number })[] = [
cell: ({ row }) => {
return (
<div className="flex flex-row items-center gap-2">
<Token />
<TokenIcon src={row.original.iconFrom} className="size-[12px]" />
{row.original.amountFrom}
</div>
);
Expand All @@ -57,7 +60,7 @@ export const columns: (ColumnDef<Transaction> & { colSpan?: number })[] = [
cell: ({ row }) => {
return (
<div className="flex flex-row items-center gap-2">
<Token size="small" />
<TokenIcon src={row.original.iconTo} className="size-[12px]" />
{row.original.amountTo}
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/SwapForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export const SwapForm = () => {
const isSwap1 = isSwappingBaseAsset || token1.address === fUSDC.address;

// the pool currently in use's price
const poolAddress = isSwappingBaseAsset ? token1!.address : token0.address;
const poolAddress = isSwappingBaseAsset ? token1.address : token0.address;

// useSimulateContract throws if connector.account is not defined
// so we must check if it exists or use a dummy address for sqrtPriceX96 and quote/quote2
Expand Down
6 changes: 3 additions & 3 deletions web/src/components/SwapPro/SwapProGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { startCase } from "lodash";
import { DurationSegmentedControl } from "@/components/DurationSegmentedControl";
import { TypographyH2 } from "@/components/ui/typography";
import ReactECharts from "echarts-for-react";
import { format, subDays } from "date-fns";
import { SwapProPoolFragmentFragment } from "@/gql/graphql";
import { format } from "date-fns";
import { SwapProPoolFilteredFragmentFragment } from "@/gql/graphql";
import { useFeatureFlag } from "@/hooks/useFeatureFlag";
import { usdFormat } from "@/lib/usdFormat";

Expand All @@ -24,7 +24,7 @@ export const Graph = ({
pool,
currentPrice,
}: {
pool?: SwapProPoolFragmentFragment;
pool?: SwapProPoolFilteredFragmentFragment;
currentPrice: string;
}) => {
const [activeGraphType, setActiveGraphType] = useState<"price" | "volume">(
Expand Down
80 changes: 80 additions & 0 deletions web/src/components/SwapPro/SwapProPoolFragment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,83 @@ export const SwapProPoolFragment = graphql(`
}
}
`);

/**
* Fragment containing the data for SwapPro, filtered by recipient swap token
*/
export const SwapProPoolFilteredFragment = graphql(`
fragment SwapProPoolFilteredFragment on SeawaterPool {
address
token {
address
symbol
}
liquidity {
liquidity
}
priceOverTime {
daily
monthly
}
volumeOverTime {
monthly {
token1 {
timestamp
valueUsd
}
fusdc {
timestamp
valueUsd
}
}
daily {
token1 {
timestamp
valueUsd
}
fusdc {
timestamp
valueUsd
}
}
}
liquidityOverTime {
daily {
timestamp
fusdc {
valueUsd
}
}
monthly {
timestamp
fusdc {
valueUsd
}
}
}
APR {
total
}
swaps(filter: $filter) {
swaps {
transactionHash
timestamp
amountIn {
valueScaled
valueUsd
token {
symbol
image
}
}
amountOut {
valueScaled
token {
symbol
image
}
}
}
}
}
`);
29 changes: 14 additions & 15 deletions web/src/components/SwapPro/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import { Graph } from "@/components/SwapPro/SwapProGraph";
import { useSwapStore } from "@/stores/useSwapStore";
import { columns, Transaction } from "@/app/_DataTable/columns";
import { DataTable } from "@/app/_DataTable/DataTable";
import { useGraphqlGlobal } from "@/hooks/useGraphql";
import { useGetFilteredPool } from "@/hooks/useGraphql";
import { useFragment } from "@/gql";
import { SwapProPoolFragment } from "@/components/SwapPro/SwapProPoolFragment";
import { SwapProPoolFilteredFragment } from "@/components/SwapPro/SwapProPoolFragment";
import { useMemo } from "react";
import { useFeatureFlag } from "@/hooks/useFeatureFlag";
import { usdFormat } from "@/lib/usdFormat";
Expand Down Expand Up @@ -48,21 +48,18 @@ export const SwapPro = ({

const isOpen = override || (!welcome && (swapPro || isLtSm));

const { data: dataGlobal, isLoading: isLoadingGlobal } = useGraphqlGlobal();
const isSwap1 =
token0.address === fUSDC.address || token1.address === fUSDC.address;
const filterToken = isSwap1 ? fUSDC.address : token1.address;
const poolToken =
token0.address === fUSDC.address ? token1.address : token0.address;

// the selected pool
const pool = useMemo(
() =>
dataGlobal?.pools?.find(
(pool) =>
pool.address.toLowerCase() === token0.address.toLowerCase() ||
pool.address.toLowerCase() === token1.address.toLowerCase(),
),
[dataGlobal?.pools, token0.address, token1.address],
const pool = useGetFilteredPool(poolToken, filterToken);
const poolSwapPro = useFragment(
SwapProPoolFilteredFragment,
pool.data?.getPool,
);

const poolSwapPro = useFragment(SwapProPoolFragment, pool);

const stakeApr = Number(poolSwapPro?.APR.total).toFixed(2);

const volume24H = useMemo(() => {
Expand Down Expand Up @@ -173,10 +170,12 @@ export const SwapPro = ({
?.map((transaction) => {
return {
id: transaction.timestamp.toString(),
value: parseFloat(transaction.amountIn.valueScaled),
value: parseFloat(transaction.amountIn.valueUsd),
rewards: 0,
time: new Date(transaction.timestamp * 1000),
amountFrom: parseFloat(transaction.amountIn.valueScaled),
iconFrom: transaction.amountIn.token.image,
iconTo: transaction.amountOut.token.image,
amountTo: parseFloat(transaction.amountOut.valueScaled),
transactionHash: transaction.transactionHash,
};
Expand Down
10 changes: 10 additions & 0 deletions web/src/gql/gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@ const documents = {
"\n fragment StakeFormPoolFragment on SeawaterPool {\n token {\n decimals\n address\n name\n symbol\n }\n }\n": types.StakeFormPoolFragmentFragmentDoc,
"\n fragment SwapFormFragment on SeawaterPool {\n address\n fee\n earnedFeesAPRFUSDC\n earnedFeesAPRToken1\n token {\n address\n decimals\n name\n symbol\n }\n }\n": types.SwapFormFragmentFragmentDoc,
"\n fragment SwapProPoolFragment on SeawaterPool {\n address\n token {\n address\n symbol\n }\n liquidity {\n liquidity\n }\n priceOverTime {\n daily\n monthly\n }\n volumeOverTime {\n monthly {\n token1 {\n timestamp\n valueUsd\n }\n fusdc {\n timestamp\n valueUsd\n }\n }\n daily {\n token1 {\n timestamp\n valueUsd\n }\n fusdc {\n timestamp\n valueUsd\n }\n }\n }\n liquidityOverTime {\n daily {\n timestamp\n fusdc {\n valueUsd\n }\n }\n monthly {\n timestamp\n fusdc {\n valueUsd\n }\n }\n }\n APR {\n total\n }\n swaps {\n swaps {\n transactionHash\n timestamp\n amountIn {\n valueScaled\n token {\n symbol\n }\n }\n amountOut {\n valueScaled\n token {\n symbol\n }\n }\n }\n }\n }\n": types.SwapProPoolFragmentFragmentDoc,
"\n fragment SwapProPoolFilteredFragment on SeawaterPool {\n address\n token {\n address\n symbol\n }\n liquidity {\n liquidity\n }\n priceOverTime {\n daily\n monthly\n }\n volumeOverTime {\n monthly {\n token1 {\n timestamp\n valueUsd\n }\n fusdc {\n timestamp\n valueUsd\n }\n }\n daily {\n token1 {\n timestamp\n valueUsd\n }\n fusdc {\n timestamp\n valueUsd\n }\n }\n }\n liquidityOverTime {\n daily {\n timestamp\n fusdc {\n valueUsd\n }\n }\n monthly {\n timestamp\n fusdc {\n valueUsd\n }\n }\n }\n APR {\n total\n }\n swaps(filter: $filter) {\n swaps {\n transactionHash\n timestamp\n amountIn {\n valueScaled\n valueUsd\n token {\n symbol\n image\n }\n }\n amountOut {\n valueScaled\n token {\n symbol\n image\n }\n }\n }\n }\n }\n": types.SwapProPoolFilteredFragmentFragmentDoc,
"\n fragment TokensFragment on SeawaterPool {\n token {\n address\n decimals\n name\n symbol\n image\n }\n }\n": types.TokensFragmentFragmentDoc,
"\n fragment FusdcFragment on Token {\n address\n decimals\n name\n symbol\n image\n }\n": types.FusdcFragmentFragmentDoc,
"\n query AllData {\n fusdc {\n address\n ...FusdcFragment\n }\n pools {\n # used for the pool selector\n address\n\n # add general fragments here\n ...SwapProPoolFragment\n ...AllPoolsFragment\n ...SelectPrimeAssetFragment\n ...SwapExploreFragment\n ...ManagePoolFragment\n ...SwapFormFragment\n ...StakeFormFragment\n ...TokensFragment\n ...ConfirmStakeFragment\n }\n }\n": types.AllDataDocument,
"\n query ForUser($wallet: String!) {\n getSwapsForUser(wallet: $wallet, first: 10) {\n data {\n swaps {\n # add transaction fragments here\n ...TradeTabTransactionsFragment\n }\n }\n }\n\n getWallet(address: $wallet) {\n # add wallet fragments here\n ...MyPositionsInventoryWalletFragment\n ...PositionsFragment\n }\n\n notes(wallet: $wallet) {\n # add notes fragments here\n ...NotesFragment\n }\n }\n": types.ForUserDocument,
"\n query queryGetPoints($wallet: String!) {\n getPointsComponent(wallet: $wallet)\n }\n": types.QueryGetPointsDocument,
"\n query queryGetPool($token: String!) {\n getPool(token: $token) {\n ...StakeFormPoolFragment\n ...ManagePoolFragment\n }\n }\n": types.QueryGetPoolDocument,
"\n query queryGetFilteredPool($token: String!, $filter: String!) {\n getPool(token: $token) {\n ...SwapProPoolFilteredFragment\n }\n }\n": types.QueryGetFilteredPoolDocument,
"\n fragment PositionsFragment on Wallet {\n id\n positions {\n positions {\n created\n served {\n timestamp\n }\n positionId\n pool {\n token {\n name\n address\n symbol\n decimals\n }\n liquidityCampaigns {\n campaignId\n tickLower\n tickUpper\n fromTimestamp\n endTimestamp\n }\n }\n lower\n upper\n liquidity {\n fusdc {\n valueUsd\n }\n token1 {\n valueUsd\n }\n }\n isVested\n }\n }\n }\n": types.PositionsFragmentFragmentDoc,
};

Expand Down Expand Up @@ -96,6 +98,10 @@ export function graphql(source: "\n fragment SwapFormFragment on SeawaterPool {
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n fragment SwapProPoolFragment on SeawaterPool {\n address\n token {\n address\n symbol\n }\n liquidity {\n liquidity\n }\n priceOverTime {\n daily\n monthly\n }\n volumeOverTime {\n monthly {\n token1 {\n timestamp\n valueUsd\n }\n fusdc {\n timestamp\n valueUsd\n }\n }\n daily {\n token1 {\n timestamp\n valueUsd\n }\n fusdc {\n timestamp\n valueUsd\n }\n }\n }\n liquidityOverTime {\n daily {\n timestamp\n fusdc {\n valueUsd\n }\n }\n monthly {\n timestamp\n fusdc {\n valueUsd\n }\n }\n }\n APR {\n total\n }\n swaps {\n swaps {\n transactionHash\n timestamp\n amountIn {\n valueScaled\n token {\n symbol\n }\n }\n amountOut {\n valueScaled\n token {\n symbol\n }\n }\n }\n }\n }\n"): (typeof documents)["\n fragment SwapProPoolFragment on SeawaterPool {\n address\n token {\n address\n symbol\n }\n liquidity {\n liquidity\n }\n priceOverTime {\n daily\n monthly\n }\n volumeOverTime {\n monthly {\n token1 {\n timestamp\n valueUsd\n }\n fusdc {\n timestamp\n valueUsd\n }\n }\n daily {\n token1 {\n timestamp\n valueUsd\n }\n fusdc {\n timestamp\n valueUsd\n }\n }\n }\n liquidityOverTime {\n daily {\n timestamp\n fusdc {\n valueUsd\n }\n }\n monthly {\n timestamp\n fusdc {\n valueUsd\n }\n }\n }\n APR {\n total\n }\n swaps {\n swaps {\n transactionHash\n timestamp\n amountIn {\n valueScaled\n token {\n symbol\n }\n }\n amountOut {\n valueScaled\n token {\n symbol\n }\n }\n }\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n fragment SwapProPoolFilteredFragment on SeawaterPool {\n address\n token {\n address\n symbol\n }\n liquidity {\n liquidity\n }\n priceOverTime {\n daily\n monthly\n }\n volumeOverTime {\n monthly {\n token1 {\n timestamp\n valueUsd\n }\n fusdc {\n timestamp\n valueUsd\n }\n }\n daily {\n token1 {\n timestamp\n valueUsd\n }\n fusdc {\n timestamp\n valueUsd\n }\n }\n }\n liquidityOverTime {\n daily {\n timestamp\n fusdc {\n valueUsd\n }\n }\n monthly {\n timestamp\n fusdc {\n valueUsd\n }\n }\n }\n APR {\n total\n }\n swaps(filter: $filter) {\n swaps {\n transactionHash\n timestamp\n amountIn {\n valueScaled\n valueUsd\n token {\n symbol\n image\n }\n }\n amountOut {\n valueScaled\n token {\n symbol\n image\n }\n }\n }\n }\n }\n"): (typeof documents)["\n fragment SwapProPoolFilteredFragment on SeawaterPool {\n address\n token {\n address\n symbol\n }\n liquidity {\n liquidity\n }\n priceOverTime {\n daily\n monthly\n }\n volumeOverTime {\n monthly {\n token1 {\n timestamp\n valueUsd\n }\n fusdc {\n timestamp\n valueUsd\n }\n }\n daily {\n token1 {\n timestamp\n valueUsd\n }\n fusdc {\n timestamp\n valueUsd\n }\n }\n }\n liquidityOverTime {\n daily {\n timestamp\n fusdc {\n valueUsd\n }\n }\n monthly {\n timestamp\n fusdc {\n valueUsd\n }\n }\n }\n APR {\n total\n }\n swaps(filter: $filter) {\n swaps {\n transactionHash\n timestamp\n amountIn {\n valueScaled\n valueUsd\n token {\n symbol\n image\n }\n }\n amountOut {\n valueScaled\n token {\n symbol\n image\n }\n }\n }\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
Expand All @@ -120,6 +126,10 @@ export function graphql(source: "\n query queryGetPoints($wallet: String!) {\n
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n query queryGetPool($token: String!) {\n getPool(token: $token) {\n ...StakeFormPoolFragment\n ...ManagePoolFragment\n }\n }\n"): (typeof documents)["\n query queryGetPool($token: String!) {\n getPool(token: $token) {\n ...StakeFormPoolFragment\n ...ManagePoolFragment\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n query queryGetFilteredPool($token: String!, $filter: String!) {\n getPool(token: $token) {\n ...SwapProPoolFilteredFragment\n }\n }\n"): (typeof documents)["\n query queryGetFilteredPool($token: String!, $filter: String!) {\n getPool(token: $token) {\n ...SwapProPoolFilteredFragment\n }\n }\n"];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
Expand Down
Loading

0 comments on commit a69458f

Please sign in to comment.