From 434b7503b1f698937a0488b67dc929d130b99ed6 Mon Sep 17 00:00:00 2001 From: nguyenlejoe Date: Tue, 16 Jan 2024 13:48:51 -0800 Subject: [PATCH] wallet transactions --- .../XYKWalletTransactionsListView.stories.tsx | 19 + .../XYKWalletTransactionsListView.tsx | 371 ++++++++++++++++++ src/utils/types/organisms.types.ts | 6 + 3 files changed, 396 insertions(+) create mode 100644 src/components/Organisms/XYK/XYKWalletTransactionsListView/XYKWalletTransactionsListView.stories.tsx create mode 100644 src/components/Organisms/XYK/XYKWalletTransactionsListView/XYKWalletTransactionsListView.tsx diff --git a/src/components/Organisms/XYK/XYKWalletTransactionsListView/XYKWalletTransactionsListView.stories.tsx b/src/components/Organisms/XYK/XYKWalletTransactionsListView/XYKWalletTransactionsListView.stories.tsx new file mode 100644 index 00000000..a7fb8bcd --- /dev/null +++ b/src/components/Organisms/XYK/XYKWalletTransactionsListView/XYKWalletTransactionsListView.stories.tsx @@ -0,0 +1,19 @@ +import { type Meta, type StoryObj } from "@storybook/react"; +import { XYKWalletTransactionsListView } from "./XYKWalletTransactionsListView"; + +type Story = StoryObj; + +const meta: Meta = { + title: "Organisms/XYK/Wallet", + component: XYKWalletTransactionsListView, +}; + +export default meta; + +export const XYKWalletTransactionsList: Story = { + args: { + chain_name: "eth-mainnet", + dex_name: "uniswap_v2", + wallet_address: "0xfc43f5f9dd45258b3aff31bdbe6561d97e8b71de", + }, +}; diff --git a/src/components/Organisms/XYK/XYKWalletTransactionsListView/XYKWalletTransactionsListView.tsx b/src/components/Organisms/XYK/XYKWalletTransactionsListView/XYKWalletTransactionsListView.tsx new file mode 100644 index 00000000..76d0ddc7 --- /dev/null +++ b/src/components/Organisms/XYK/XYKWalletTransactionsListView/XYKWalletTransactionsListView.tsx @@ -0,0 +1,371 @@ +import { type Option, None, Some } from "@/utils/option"; +import { type ExchangeTransaction } from "@covalenthq/client-sdk"; +import { POOL_TRANSACTION_MAP } from "@/utils/constants/shared.constants"; +import { Fragment, useEffect, useState } from "react"; +import { + type ColumnDef, + type SortingState, + flexRender, + getCoreRowModel, + getSortedRowModel, + useReactTable, +} from "@tanstack/react-table"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table"; +import { Checkbox } from "@/components/ui/checkbox"; +import { Skeleton } from "@/components/ui/skeleton"; +import { timestampParser } from "@/utils/functions"; +import { Badge } from "@/components/ui/badge"; +import { TableHeaderSorting } from "@/components/ui/tableHeaderSorting"; +import { GRK_SIZES } from "@/utils/constants/shared.constants"; +import { type XYKWalletTransactionsListViewProps } from "@/utils/types/organisms.types"; +import { useCovalent } from "@/utils/store/Covalent"; +import { handleTokenTransactions } from "@/utils/functions/pretty-exchange-amount"; +import { handleExchangeType } from "@/utils/functions/exchange-type"; + +const columns: ColumnDef[] = [ + { + id: "select", + header: ({ table }) => ( + + table.toggleAllPageRowsSelected(!!value) + } + aria-label="Select all" + /> + ), + cell: ({ row }) => ( + row.toggleSelected(!!value)} + aria-label="Select row" + /> + ), + enableSorting: false, + enableHiding: false, + }, + { + accessorKey: "block_signed_at", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const t = row.getValue("block_signed_at") as string; + + return
{timestampParser(t, "relative")}
; + }, + }, + { + accessorKey: "act", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const token_0 = row.original.token_0; + const token_1 = row.original.token_1; + + if (row.original.act !== "SWAP") { + return ( +
+ + {POOL_TRANSACTION_MAP[row.original.act].name} + {" "} + {token_0.contract_ticker_symbol}{" "} + {row.original.act === "SWAP" ? "for" : "and"}{" "} + {token_1.contract_ticker_symbol} +
+ ); + } + const token_in = + handleExchangeType(row.original, 0) === "in" + ? token_0 + : token_1; + const token_out = + handleExchangeType(row.original, 0) === "out" + ? token_0 + : token_1; + return ( +
+ + {POOL_TRANSACTION_MAP[row.original.act].name} + {" "} + {token_in.contract_ticker_symbol}{" "} + {row.original.act === "SWAP" ? "for" : "and"}{" "} + {token_out.contract_ticker_symbol} +
+ ); + }, + }, + { + id: "total_quote", + accessorKey: "total_quote", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + return <>{row.original.pretty_total_quote}; + }, + }, + { + id: "amount_0", + accessorKey: "amount_0", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + if (row.original.act !== "SWAP") { + return ( + + {handleTokenTransactions( + row.original.act, + "0", + row.original, + row.original.token_0.contract_decimals + )}{" "} + {row.original.token_0.contract_ticker_symbol} + + ); + } + const token_in = + handleExchangeType(row.original, 0) === "in" ? "0" : "1"; + return ( + + {handleTokenTransactions( + row.original.act, + token_in, + row.original, + row.original[`token_${token_in}`].contract_decimals + )}{" "} + {row.original[`token_${token_in}`].contract_ticker_symbol} + + ); + }, + }, + { + id: "amount_1", + accessorKey: "amount_1", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + if (row.original.act !== "SWAP") { + return ( + + {handleTokenTransactions( + row.original.act, + "1", + row.original, + row.original.token_1.contract_decimals + )}{" "} + {row.original.token_1.contract_ticker_symbol} + + ); + } + const token_in = + handleExchangeType(row.original, 0) === "out" ? "0" : "1"; + const token_amount = handleTokenTransactions( + row.original.act, + token_in, + row.original, + row.original[`token_${token_in}`].contract_decimals + ); + return ( + + {token_amount}{" "} + {row.original[`token_${token_in}`].contract_ticker_symbol} + + ); + }, + }, +]; + +export const XYKWalletTransactionsListView: React.FC< + XYKWalletTransactionsListViewProps +> = ({ chain_name, dex_name, wallet_address }) => { + const { covalentClient } = useCovalent(); + + const [sorting, setSorting] = useState([ + { + id: "block_signed_at", + desc: true, + }, + ]); + const [rowSelection, setRowSelection] = useState({}); + const [maybeResult, setResult] = + useState>(None); + const [error, setError] = useState({ error: false, error_message: "" }); + + useEffect(() => { + setResult(None); + (async () => { + let response; + try { + response = + await covalentClient.XykService.getTransactionsForAccountAddress( + chain_name, + dex_name, + wallet_address.trim() + ); + console.log(response); + setResult(new Some(response.data.items)); + + setError({ error: false, error_message: "" }); + } catch (error) { + setResult(new Some([])); + setError({ + error: response ? response.error : false, + error_message: response ? response.error_message : "", + }); + } + })(); + }, [wallet_address, dex_name, chain_name]); + + const table = useReactTable({ + data: maybeResult.match({ + None: () => [], + Some: (result) => result, + }), + columns, + onSortingChange: setSorting, + getCoreRowModel: getCoreRowModel(), + getSortedRowModel: getSortedRowModel(), + onRowSelectionChange: setRowSelection, + state: { + sorting, + rowSelection, + }, + }); + + const body = maybeResult.match({ + None: () => ( + + + + + +
+ +
+
+ +
+ +
+
+ +
+ +
+
+
+ ), + Some: () => { + return error.error ? ( + + + {error.error_message} + + + ) : !error.error && table.getRowModel().rows?.length ? ( + table.getRowModel().rows.map((row) => { + if ( + !row.original.token_0?.contract_ticker_symbol && + !row.original.token_1?.contract_ticker_symbol + ) + return; + return ( + + + {row.getVisibleCells().map((cell) => ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext() + )} + + ))} + + + ); + }) + ) : ( + + + No results. + + + ); + }, + }); + + return ( +
+ + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + + {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef + .header, + header.getContext() + )} + + ); + })} + + ))} + + {body} +
+
+ ); +}; diff --git a/src/utils/types/organisms.types.ts b/src/utils/types/organisms.types.ts index bfbba25c..0e1558aa 100644 --- a/src/utils/types/organisms.types.ts +++ b/src/utils/types/organisms.types.ts @@ -72,6 +72,12 @@ export interface XYKTokenTransactionsListViewProps { token_address: string; } +export interface XYKWalletTransactionsListViewProps { + chain_name: Chain; + dex_name: string; + wallet_address: string; +} + export interface TokenBalancesListViewProps { chain_names: Chain[]; address: string;