From 2425aaad13d75dcd844f0c6fa195775b8053be44 Mon Sep 17 00:00:00 2001 From: Matt Upham <30577966+mattupham@users.noreply.github.com> Date: Mon, 5 Aug 2024 17:14:31 -0700 Subject: [PATCH 01/21] Add scaffolding for recent transactions --- .../web/components/buttons/link-button.tsx | 4 ++-- .../complex/portfolio/portfolio-page.tsx | 17 ++------------ .../transactions/recent-transfers.tsx | 23 +++++++++++++++++++ packages/web/localizations/en.json | 4 +++- 4 files changed, 30 insertions(+), 18 deletions(-) diff --git a/packages/web/components/buttons/link-button.tsx b/packages/web/components/buttons/link-button.tsx index 5257240d89..68bf40a410 100644 --- a/packages/web/components/buttons/link-button.tsx +++ b/packages/web/components/buttons/link-button.tsx @@ -12,7 +12,7 @@ export function LinkButton({ className: optionalClassNames, }: { label: string; - icon: ReactElement; + icon?: ReactElement; ariaLabel: string; href: string; className?: string; @@ -25,7 +25,7 @@ export function LinkButton({ aria-label={ariaLabel} className={`flex flex-row gap-2 ${optionalClassNames ?? ""}`} > - {icon} + {icon && icon}

{label}

diff --git a/packages/web/components/complex/portfolio/portfolio-page.tsx b/packages/web/components/complex/portfolio/portfolio-page.tsx index 916d260e01..6e5401c6f4 100644 --- a/packages/web/components/complex/portfolio/portfolio-page.tsx +++ b/packages/web/components/complex/portfolio/portfolio-page.tsx @@ -10,7 +10,7 @@ import { UserZeroBalanceTableSplash } from "~/components/complex/portfolio/user- import { WalletDisconnectedSplash } from "~/components/complex/portfolio/wallet-disconnected-splash"; import { Spinner } from "~/components/loaders"; import { AssetBalancesTable } from "~/components/table/asset-balances"; -import { RecentTransfers } from "~/components/transactions/recent-transfers"; +import { RecentActivity } from "~/components/transactions/recent-transfers"; import { useDimension, useTranslation, useWalletSelect } from "~/hooks"; import { useBridge } from "~/hooks/bridge"; import { useStore } from "~/stores"; @@ -105,15 +105,6 @@ export const PortfolioPage: FunctionComponent = () => { )} - - {({ selected }) => ( -
- {t("portfolio.recentTransfers")} -
- )} -
{!isTotalValueFetched ? (
@@ -133,16 +124,12 @@ export const PortfolioPage: FunctionComponent = () => { - -
- -
-
)}
+ {!isLoadingAllocation && !userHasNoAssets && ( )} diff --git a/packages/web/components/transactions/recent-transfers.tsx b/packages/web/components/transactions/recent-transfers.tsx index 2ec2d5f555..4d2a3f4598 100644 --- a/packages/web/components/transactions/recent-transfers.tsx +++ b/packages/web/components/transactions/recent-transfers.tsx @@ -3,6 +3,7 @@ import { makeMinimalAsset } from "@osmosis-labs/utils"; import { observer } from "mobx-react-lite"; import { FunctionComponent } from "react"; +import { LinkButton } from "~/components/buttons/link-button"; import { NoTransactionsSplash } from "~/components/transactions/no-transactions-splash"; import { AssetLists } from "~/config/generated/asset-lists"; import { useTranslation, useWalletSelect } from "~/hooks"; @@ -91,3 +92,25 @@ const UserRecentTransfers: FunctionComponent<{ address: string }> = observer( ); } ); + +export const RecentActivity: FunctionComponent = observer(() => { + const { accountStore } = useStore(); + const { isLoading: isWalletLoading } = useWalletSelect(); + + const account = accountStore.getWallet(accountStore.osmosisChainId); + + const { t } = useTranslation(); + return ( +
+
+
{t("portfolio.recentActivity")}
+ +
+
+ ); +}); diff --git a/packages/web/localizations/en.json b/packages/web/localizations/en.json index adb56301e1..c412518352 100644 --- a/packages/web/localizations/en.json +++ b/packages/web/localizations/en.json @@ -334,7 +334,9 @@ "pooled": "Pooled", "other": "Other", "all": "All", - "assets": "Assets" + "assets": "Assets", + "recentActivity": "Recent activity", + "seeAll": "See all" }, "buyTokens": "Buy tokens", "components": { From 816fc4e46553dd41a9126b5534355d9386bbffc7 Mon Sep 17 00:00:00 2001 From: Matt Upham <30577966+mattupham@users.noreply.github.com> Date: Tue, 6 Aug 2024 17:46:30 -0700 Subject: [PATCH 02/21] Clean up component --- .../web/components/buttons/link-button.tsx | 4 +- .../complex/portfolio/portfolio-page.tsx | 5 +- .../transactions/recent-transfers.tsx | 54 ++++++++----------- 3 files changed, 30 insertions(+), 33 deletions(-) diff --git a/packages/web/components/buttons/link-button.tsx b/packages/web/components/buttons/link-button.tsx index 68bf40a410..4e8fc512c4 100644 --- a/packages/web/components/buttons/link-button.tsx +++ b/packages/web/components/buttons/link-button.tsx @@ -10,15 +10,17 @@ export function LinkButton({ ariaLabel, href, className: optionalClassNames, + size = "default", }: { label: string; icon?: ReactElement; ariaLabel: string; href: string; className?: string; + size: "sm" | "md" | "default"; }) { return ( - + + +
+ + ) : ( + + )} + + ); +}); + +const UserPositionsSection: FunctionComponent<{ address?: string }> = ({ + address, +}) => { + const { t } = useTranslation(); + const router = useRouter(); + const { + hasPositions, + hasPools, + isLoading: isLoadingPositions, + } = useUserPositionsData(address); + + if (isLoadingPositions) { + return ( +
+ +
+ ); + } + + if (hasPositions || hasPools) + return ( + <> + {hasPositions && ( +
+ + {t("portfolio.yourSuperchargedPositions")} + + +
+ )} + {hasPools && ( +
+ + {t("portfolio.yourLiquidityPools")} + + +
+ )} + + ); + + return ( +
+ no positions +
+
{t("portfolio.noPositions")}
+

+ {t("portfolio.unlockPotential")} +

+ +
+
+ ); +}; + +const UserZeroBalanceTableSplash: FunctionComponent = () => { + const { t } = useTranslation(); + const { startBridge, fiatRampSelection } = useBridge(); + + return ( +
+ no balances +
{t("portfolio.noAssets", { osmosis: "Osmosis" })}
+

{t("portfolio.getStarted")}

+
+ + +
+
+ ); +}; + +const GetStartedWithOsmosis: FunctionComponent = () => { + const { chainStore } = useStore(); + const { t } = useTranslation(); + + const { onOpenWalletSelect } = useWalletSelect(); + + return ( +
+

{t("portfolio.connectWallet")}

+ +
+ ); +}; + +const WalletDisconnectedSplash: FunctionComponent = () => ( +
+ home + home +
+); + +function useUserPositionsData(address: string | undefined) { + const { data: positions, isLoading: isLoadingUserPositions } = + api.local.concentratedLiquidity.getUserPositions.useQuery( + { + userOsmoAddress: address ?? "", + }, + { + enabled: Boolean(address), + + // expensive query + trpc: { + context: { + skipBatch: true, + }, + }, + } + ); + + const hasPositions = Boolean(positions?.length); + + const { data: allMyPoolDetails, isLoading: isLoadingMyPoolDetails } = + api.edge.pools.getUserPools.useQuery( + { + userOsmoAddress: address ?? "", + }, + { + enabled: Boolean(address), + + // expensive query + trpc: { + context: { + skipBatch: true, + }, + }, + } + ); + const hasPools = Boolean(allMyPoolDetails?.length); + + return { + hasPositions, + hasPools, + isLoading: isLoadingUserPositions || isLoadingMyPoolDetails, + }; +} diff --git a/packages/web/components/complex/portfolio/portfolio-page.tsx b/packages/web/components/complex/portfolio/portfolio-page.tsx index e11cff2379..1ddf98d216 100644 --- a/packages/web/components/complex/portfolio/portfolio-page.tsx +++ b/packages/web/components/complex/portfolio/portfolio-page.tsx @@ -10,7 +10,7 @@ import { UserZeroBalanceTableSplash } from "~/components/complex/portfolio/user- import { WalletDisconnectedSplash } from "~/components/complex/portfolio/wallet-disconnected-splash"; import { Spinner } from "~/components/loaders"; import { AssetBalancesTable } from "~/components/table/asset-balances"; -import { RecentActivity } from "~/components/transactions/recent-activity"; +import { RecentActivity } from "~/components/transactions/recent-activity/recent-activity"; import { useDimension, useTranslation, useWalletSelect } from "~/hooks"; import { useBridge } from "~/hooks/bridge"; import { useStore } from "~/stores"; diff --git a/packages/web/components/transactions/recent-activity/recent-activity-transaction.tsx b/packages/web/components/transactions/recent-activity/recent-activity-transaction.tsx new file mode 100644 index 0000000000..d989cd0c21 --- /dev/null +++ b/packages/web/components/transactions/recent-activity/recent-activity-transaction.tsx @@ -0,0 +1,266 @@ +import { CoinPretty, PricePretty } from "@keplr-wallet/unit"; +import classNames from "classnames"; +import { FunctionComponent } from "react"; + +import { FallbackImg, Icon } from "~/components/assets"; +import { displayFiatPrice } from "~/components/transactions/transaction-utils"; +import { useTranslation } from "~/hooks"; +import { theme } from "~/tailwind.config"; +import { formatPretty } from "~/utils/formatter"; + +import { Spinner } from "../../loaders"; + +export type TransactionStatus = "pending" | "success" | "failed"; + +type Effect = "swap" | "deposit" | "withdraw"; + +interface Transaction { + isSelected?: boolean; + status: TransactionStatus; + /** At a high level- what this transaction does. */ + effect: Effect; + title: { + [key in TransactionStatus]: string; + }; + caption?: string; + tokenConversion?: { + tokenIn: { + amount: CoinPretty; + value?: PricePretty; + }; + tokenOut: { + amount: CoinPretty; + value?: PricePretty; + }; + }; + transfer?: { + direction: "deposit" | "withdraw"; + amount: CoinPretty; + value?: PricePretty; + }; + onClick?: () => void; +} + +export const RecentTransferRow: FunctionComponent = ({ + status, + effect, + title, + transfer, +}) => { + const effectIconId = effect === "swap" ? "swap" : "down-arrow"; + + return ( +
+
+ {status === "pending" ? ( + + ) : ( +
+ {status === "success" ? ( + effect === "withdraw" ? ( + + ) : ( + + ) + ) : ( + + )} +
+ )} +
+

+ {title[status]} +

+
+
+ {transfer && } +
+ ); + + // return ( + //
onClick?.()} + // > + //
+ // {status === "pending" ? ( + // + // ) : ( + //
+ // {status === "success" ? ( + // effect === "withdraw" ? ( + // + // ) : ( + // + // ) + // ) : ( + // + // )} + //
+ // )} + + //
+ //

+ // {title[status]} + //

+ // {tokenConversion && ( + //
+ // {formatPretty(tokenConversion.tokenOut.amount, { + // maxDecimals: 6, + // })} + // + //
+ // )} + //
+ //
+ // {caption &&

{caption}

} + // {tokenConversion && ( + // + // )} + // {transfer && } + //
+ // ); +}; + +/** UI for displaying one token being converted into another by this transaction. */ +const TokenConversion: FunctionComponent< + { status: TransactionStatus; effect: Effect } & NonNullable< + Transaction["tokenConversion"] + > +> = ({ status, tokenIn, tokenOut, effect }) => { + const { t } = useTranslation(); + return ( +
+
+
+ {tokenIn.value && ( +
+ {formatPretty(tokenIn.amount, { maxDecimals: 6 })} +
+ )} +
+ {displayFiatPrice(tokenIn?.value, "-", t)} +
+
+ +
+ +
+ +
+ {tokenOut.value && ( +
+ {formatPretty(tokenOut.amount, { maxDecimals: 6 })} +
+ )} +
+ {displayFiatPrice(tokenOut?.value, "+", t)} +
+
+
+
+ ); +}; + +/** UI for displaying a token being deposited or withdrawn from Osmosis. */ +export const TokenTransfer: FunctionComponent< + { + status: TransactionStatus; + } & NonNullable +> = ({ status, direction, amount, value }) => ( +
+ +
+ {formatPretty(amount, { maxDecimals: 6 })} +
+ {value && ( +
+ {direction === "withdraw" ? "-" : "+"} {value.symbol} + {Number(value.toDec().abs().toString()).toFixed(2)} +
+ )} +
+); diff --git a/packages/web/components/transactions/recent-activity.tsx b/packages/web/components/transactions/recent-activity/recent-activity.tsx similarity index 90% rename from packages/web/components/transactions/recent-activity.tsx rename to packages/web/components/transactions/recent-activity/recent-activity.tsx index f868d54c06..bea018356b 100644 --- a/packages/web/components/transactions/recent-activity.tsx +++ b/packages/web/components/transactions/recent-activity/recent-activity.tsx @@ -9,9 +9,9 @@ import { AssetLists } from "~/config/generated/asset-lists"; import { useTranslation, useWalletSelect } from "~/hooks"; import { useStore } from "~/stores"; -import { Spinner } from "../loaders"; -import { TransactionRow } from "./transaction-row"; -import { useRecentTransfers } from "./use-recent-transfers"; +import { Spinner } from "../../loaders"; +import { useRecentTransfers } from "../use-recent-transfers"; +import { RecentTransferRow } from "./recent-activity-transaction"; export const RecentActivity: FunctionComponent = observer(() => { const { accountStore } = useStore(); @@ -23,6 +23,8 @@ export const RecentActivity: FunctionComponent = observer(() => { const recentTransfers = useRecentTransfers(account?.address); + console.log("Recent Transfers: ", recentTransfers); + return (
@@ -35,7 +37,7 @@ export const RecentActivity: FunctionComponent = observer(() => { size="sm" />
-
+
{isWalletLoading ? ( ) : recentTransfers?.length === 0 ? ( @@ -51,6 +53,8 @@ export const RecentActivity: FunctionComponent = observer(() => { ? "failed" : "pending"; + console.log("simplifiedStatus: ", simplifiedStatus); + const coinAmount = amount.split(" ")[0]; const coinDenom = amount.split(" ")[1]; const asset = AssetLists.flatMap(({ assets }) => assets).find( @@ -72,7 +76,7 @@ export const RecentActivity: FunctionComponent = observer(() => { : t("assets.historyTable.failDeposit"); return ( - Date: Tue, 6 Aug 2024 23:11:52 -0700 Subject: [PATCH 05/21] Clean up simplified status --- .../recent-activity/recent-activity.tsx | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/web/components/transactions/recent-activity/recent-activity.tsx b/packages/web/components/transactions/recent-activity/recent-activity.tsx index bea018356b..51483e4adc 100644 --- a/packages/web/components/transactions/recent-activity/recent-activity.tsx +++ b/packages/web/components/transactions/recent-activity/recent-activity.tsx @@ -1,4 +1,5 @@ import { CoinPretty, Dec, DecUtils } from "@keplr-wallet/unit"; +import { TransferStatus } from "@osmosis-labs/bridge"; import { makeMinimalAsset } from "@osmosis-labs/utils"; import { observer } from "mobx-react-lite"; import { FunctionComponent } from "react"; @@ -44,16 +45,14 @@ export const RecentActivity: FunctionComponent = observer(() => { ) : ( recentTransfers.map(({ txHash, status, amount, isWithdraw }) => { - const simplifiedStatus = - status === "success" - ? "success" - : status === "refunded" || - status === "connection-error" || - status === "failed" - ? "failed" - : "pending"; + const getSimplifiedStatus = (status: TransferStatus) => { + if (status === "success") return "success"; + if (["refunded", "connection-error", "failed"].includes(status)) + return "failed"; + return "pending"; + }; - console.log("simplifiedStatus: ", simplifiedStatus); + const simplifiedStatus = getSimplifiedStatus(status); const coinAmount = amount.split(" ")[0]; const coinDenom = amount.split(" ")[1]; From 206e5c85cf1e03569acb1c4dd11d3a08d9589a15 Mon Sep 17 00:00:00 2001 From: Matt Upham <30577966+mattupham@users.noreply.github.com> Date: Tue, 6 Aug 2024 23:43:00 -0700 Subject: [PATCH 06/21] render transactions --- .../web/components/buttons/link-button.tsx | 4 +- ...sx => recent-activity-transaction-row.tsx} | 216 +++++++++--------- .../recent-activity/recent-activity.tsx | 67 +++++- 3 files changed, 176 insertions(+), 111 deletions(-) rename packages/web/components/transactions/recent-activity/{recent-activity-transaction.tsx => recent-activity-transaction-row.tsx} (55%) diff --git a/packages/web/components/buttons/link-button.tsx b/packages/web/components/buttons/link-button.tsx index 4e8fc512c4..370bac3b09 100644 --- a/packages/web/components/buttons/link-button.tsx +++ b/packages/web/components/buttons/link-button.tsx @@ -17,10 +17,10 @@ export function LinkButton({ ariaLabel: string; href: string; className?: string; - size: "sm" | "md" | "default"; + size?: "sm" | "md" | "default"; }) { return ( -
); +}; + +export const RecentActivityTransactionRow: FunctionComponent = ({ + status, + effect, + title, + caption, + tokenConversion, + transfer, +}) => { + const effectIconId = effect === "swap" ? "swap" : "down-arrow"; - // return ( - //
onClick?.()} - // > - //
- // {status === "pending" ? ( - // - // ) : ( - //
- // {status === "success" ? ( - // effect === "withdraw" ? ( - // - // ) : ( - // - // ) - // ) : ( - // - // )} - //
- // )} + const { t } = useTranslation(); + + return ( +
+
+ {status === "pending" ? ( + + ) : ( +
+ {status === "success" ? ( + effect === "withdraw" ? ( + + ) : ( + + ) + ) : ( + + )} +
+ )} - //
- //

- // {title[status]} - //

- // {tokenConversion && ( - //
- // {formatPretty(tokenConversion.tokenOut.amount, { - // maxDecimals: 6, - // })} - // - //
- // )} - //
- //
- // {caption &&

{caption}

} - // {tokenConversion && ( - // - // )} - // {transfer && } - //
- // ); +
+
+

{title[status]}

+ {tokenConversion && ( +
+ {displayFiatPrice(tokenConversion.tokenIn?.value, "", t)}{" "} + {tokenConversion.tokenOut.amount.denom}{" "} + {" "} + {tokenConversion.tokenIn.amount.denom} +
+ )} +
+ {tokenConversion && ( +
+ {formatPretty(tokenConversion.tokenOut.amount, { + maxDecimals: 6, + })} + +
+ )} +
+
+ {caption &&

{caption}

} + {tokenConversion && ( + + )} + {transfer && } +
+ ); }; /** UI for displaying one token being converted into another by this transaction. */ @@ -167,27 +210,10 @@ const TokenConversion: FunctionComponent< { status: TransactionStatus; effect: Effect } & NonNullable< Transaction["tokenConversion"] > -> = ({ status, tokenIn, tokenOut, effect }) => { - const { t } = useTranslation(); +> = ({ tokenIn, tokenOut }) => { return (
-
- {tokenIn.value && ( -
- {formatPretty(tokenIn.amount, { maxDecimals: 6 })} -
- )} -
- {displayFiatPrice(tokenIn?.value, "-", t)} -
-
-
- {tokenOut.value && ( -
- {formatPretty(tokenOut.amount, { maxDecimals: 6 })} -
- )} -
- {displayFiatPrice(tokenOut?.value, "+", t)} -
-
); diff --git a/packages/web/components/transactions/recent-activity/recent-activity.tsx b/packages/web/components/transactions/recent-activity/recent-activity.tsx index 51483e4adc..d48293c977 100644 --- a/packages/web/components/transactions/recent-activity/recent-activity.tsx +++ b/packages/web/components/transactions/recent-activity/recent-activity.tsx @@ -1,5 +1,6 @@ import { CoinPretty, Dec, DecUtils } from "@keplr-wallet/unit"; import { TransferStatus } from "@osmosis-labs/bridge"; +import { FormattedTransaction } from "@osmosis-labs/server"; import { makeMinimalAsset } from "@osmosis-labs/utils"; import { observer } from "mobx-react-lite"; import { FunctionComponent } from "react"; @@ -9,25 +10,48 @@ import { NoTransactionsSplash } from "~/components/transactions/no-transactions- import { AssetLists } from "~/config/generated/asset-lists"; import { useTranslation, useWalletSelect } from "~/hooks"; import { useStore } from "~/stores"; +import { api } from "~/utils/trpc"; import { Spinner } from "../../loaders"; import { useRecentTransfers } from "../use-recent-transfers"; -import { RecentTransferRow } from "./recent-activity-transaction"; +import { + RecentActivityTransactionRow, + RecentActivityTransferRow, +} from "./recent-activity-transaction-row"; export const RecentActivity: FunctionComponent = observer(() => { const { accountStore } = useStore(); const { isLoading: isWalletLoading } = useWalletSelect(); - const account = accountStore.getWallet(accountStore.osmosisChainId); + const wallet = accountStore.getWallet(accountStore.osmosisChainId); const { t } = useTranslation(); - const recentTransfers = useRecentTransfers(account?.address); + const recentTransfers = useRecentTransfers(wallet?.address); console.log("Recent Transfers: ", recentTransfers); + const { data: transactionsData, isFetching: isGetTransactionsFetching } = + api.edge.transactions.getTransactions.useQuery( + { + address: wallet?.address || "", + page: "0", + pageSize: "100", + }, + { + enabled: Boolean(wallet?.isWalletConnected && wallet?.address), + } + ); + + const isLoading = isWalletLoading || isGetTransactionsFetching; + + const { transactions } = transactionsData ?? { + transactions: [], + hasNextPage: false, + }; + return ( -
+
{t("portfolio.recentActivity")}
{ />
- {isWalletLoading ? ( + {transactions?.slice(0, 5).map((transaction: FormattedTransaction) => { + return ( + + ); + })} + {isLoading ? ( ) : recentTransfers?.length === 0 ? ( @@ -75,7 +130,7 @@ export const RecentActivity: FunctionComponent = observer(() => { : t("assets.historyTable.failDeposit"); return ( - Date: Tue, 6 Aug 2024 23:47:11 -0700 Subject: [PATCH 07/21] Clean up --- .../recent-activity-transaction-row.tsx | 22 +++++-------------- .../recent-activity/recent-activity.tsx | 2 +- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx b/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx index 7b66dccaa6..908fd98c4c 100644 --- a/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx +++ b/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx @@ -171,12 +171,7 @@ export const RecentActivityTransactionRow: FunctionComponent = ({
{displayFiatPrice(tokenConversion.tokenIn?.value, "", t)}{" "} {tokenConversion.tokenOut.amount.denom}{" "} - {" "} + {" "} {tokenConversion.tokenIn.amount.denom}
)} @@ -212,31 +207,24 @@ const TokenConversion: FunctionComponent< > > = ({ tokenIn, tokenOut }) => { return ( -
-
+
+
- -
+ +
diff --git a/packages/web/components/transactions/recent-activity/recent-activity.tsx b/packages/web/components/transactions/recent-activity/recent-activity.tsx index d48293c977..cbe87cac65 100644 --- a/packages/web/components/transactions/recent-activity/recent-activity.tsx +++ b/packages/web/components/transactions/recent-activity/recent-activity.tsx @@ -63,7 +63,7 @@ export const RecentActivity: FunctionComponent = observer(() => { />
- {transactions?.slice(0, 5).map((transaction: FormattedTransaction) => { + {transactions?.slice(0, 3).map((transaction: FormattedTransaction) => { return ( Date: Wed, 7 Aug 2024 00:00:09 -0700 Subject: [PATCH 08/21] Merge lists --- .../recent-activity/recent-activity.tsx | 202 ++++++++++-------- 1 file changed, 118 insertions(+), 84 deletions(-) diff --git a/packages/web/components/transactions/recent-activity/recent-activity.tsx b/packages/web/components/transactions/recent-activity/recent-activity.tsx index cbe87cac65..df74eb1ed9 100644 --- a/packages/web/components/transactions/recent-activity/recent-activity.tsx +++ b/packages/web/components/transactions/recent-activity/recent-activity.tsx @@ -1,6 +1,5 @@ import { CoinPretty, Dec, DecUtils } from "@keplr-wallet/unit"; import { TransferStatus } from "@osmosis-labs/bridge"; -import { FormattedTransaction } from "@osmosis-labs/server"; import { makeMinimalAsset } from "@osmosis-labs/utils"; import { observer } from "mobx-react-lite"; import { FunctionComponent } from "react"; @@ -19,6 +18,8 @@ import { RecentActivityTransferRow, } from "./recent-activity-transaction-row"; +const ACTIVITY_LIMIT = 5; + export const RecentActivity: FunctionComponent = observer(() => { const { accountStore } = useStore(); const { isLoading: isWalletLoading } = useWalletSelect(); @@ -50,6 +51,34 @@ export const RecentActivity: FunctionComponent = observer(() => { hasNextPage: false, }; + const mergedActivity = [ + ...transactions.map((tx) => ({ + ...tx, + type: "transaction", + compareDate: new Date(tx.blockTimestamp), + compareTxHash: tx.hash, + })), + ...recentTransfers.map((transfer) => ({ + ...transfer, + type: "recentTransfer", + compareDate: new Date(transfer.createdAtMs), + compareTxHash: transfer.txHash, + })), + ]; + + const sortedActivity = mergedActivity.sort( + (a, b) => b.compareDate.getTime() - a.compareDate.getTime() + ); + + // filter out duplicate transactions (edge case) + const uniqueActivity = sortedActivity.filter((item, index, self) => { + return ( + index === self.findIndex((t) => t.compareTxHash === item.compareTxHash) + ); + }); + + const topActivity = uniqueActivity.slice(0, ACTIVITY_LIMIT); + return (
@@ -63,93 +92,98 @@ export const RecentActivity: FunctionComponent = observer(() => { />
- {transactions?.slice(0, 3).map((transaction: FormattedTransaction) => { - return ( - - ); - })} {isLoading ? ( - ) : recentTransfers?.length === 0 ? ( + ) : topActivity?.length === 0 ? ( ) : ( - recentTransfers.map(({ txHash, status, amount, isWithdraw }) => { - const getSimplifiedStatus = (status: TransferStatus) => { - if (status === "success") return "success"; - if (["refunded", "connection-error", "failed"].includes(status)) - return "failed"; - return "pending"; - }; - - const simplifiedStatus = getSimplifiedStatus(status); - - const coinAmount = amount.split(" ")[0]; - const coinDenom = amount.split(" ")[1]; - const asset = AssetLists.flatMap(({ assets }) => assets).find( - ({ symbol }) => symbol === coinDenom - ); - - if (!asset) return null; - - const currency = makeMinimalAsset(asset); - - const pendingText = isWithdraw - ? t("assets.historyTable.pendingWithdraw") - : t("assets.historyTable.pendingDeposit"); - const successText = isWithdraw - ? t("assets.historyTable.successWithdraw") - : t("assets.historyTable.successDeposit"); - const failedText = isWithdraw - ? t("assets.historyTable.failWithdraw") - : t("assets.historyTable.failDeposit"); - - return ( - - ); + topActivity.map((activity) => { + if (activity.type === "transaction") { + return ( + + ); + } + + if (activity.type === "recentTransfer") { + const getSimplifiedStatus = (status: TransferStatus) => { + if (status === "success") return "success"; + if (["refunded", "connection-error", "failed"].includes(status)) + return "failed"; + return "pending"; + }; + + const simplifiedStatus = getSimplifiedStatus(activity.status); + + const coinAmount = activity.amount.split(" ")[0]; + const coinDenom = activity.amount.split(" ")[1]; + const asset = AssetLists.flatMap(({ assets }) => assets).find( + ({ symbol }) => symbol === coinDenom + ); + + if (!asset) return null; + + const currency = makeMinimalAsset(asset); + + const pendingText = activity.isWithdraw + ? t("assets.historyTable.pendingWithdraw") + : t("assets.historyTable.pendingDeposit"); + const successText = activity.isWithdraw + ? t("assets.historyTable.successWithdraw") + : t("assets.historyTable.successDeposit"); + const failedText = activity.isWithdraw + ? t("assets.historyTable.failWithdraw") + : t("assets.historyTable.failDeposit"); + + return ( + + ); + } + + return null; }) )}
From 0f7bbb62dbaab88300253d13c6bba91a475ff3b2 Mon Sep 17 00:00:00 2001 From: Matt Upham <30577966+mattupham@users.noreply.github.com> Date: Wed, 7 Aug 2024 00:10:27 -0700 Subject: [PATCH 09/21] Fix types --- .../recent-activity-transaction-row.tsx | 8 +- .../recent-activity/recent-activity.tsx | 73 +++++++++++++------ 2 files changed, 53 insertions(+), 28 deletions(-) diff --git a/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx b/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx index 908fd98c4c..00320a8034 100644 --- a/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx +++ b/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx @@ -78,9 +78,7 @@ export const RecentActivityTransferRow: FunctionComponent = ({ return (
{status === "pending" ? ( @@ -133,9 +131,7 @@ export const RecentActivityTransactionRow: FunctionComponent = ({ return (
{status === "pending" ? ( diff --git a/packages/web/components/transactions/recent-activity/recent-activity.tsx b/packages/web/components/transactions/recent-activity/recent-activity.tsx index df74eb1ed9..cf88111ab2 100644 --- a/packages/web/components/transactions/recent-activity/recent-activity.tsx +++ b/packages/web/components/transactions/recent-activity/recent-activity.tsx @@ -1,5 +1,6 @@ import { CoinPretty, Dec, DecUtils } from "@keplr-wallet/unit"; import { TransferStatus } from "@osmosis-labs/bridge"; +import { FormattedTransaction } from "@osmosis-labs/server"; import { makeMinimalAsset } from "@osmosis-labs/utils"; import { observer } from "mobx-react-lite"; import { FunctionComponent } from "react"; @@ -12,12 +13,24 @@ import { useStore } from "~/stores"; import { api } from "~/utils/trpc"; import { Spinner } from "../../loaders"; -import { useRecentTransfers } from "../use-recent-transfers"; +import { RecentTransfer, useRecentTransfers } from "../use-recent-transfers"; import { RecentActivityTransactionRow, RecentActivityTransferRow, } from "./recent-activity-transaction-row"; +type ActivityType = "transaction" | "recentTransfer"; + +interface MergedActivityMetadata { + type: ActivityType; + compareDate: Date; + compareTxHash: string; +} + +type MergedActivity = + | (RecentTransfer & MergedActivityMetadata) + | (FormattedTransaction & MergedActivityMetadata); + const ACTIVITY_LIMIT = 5; export const RecentActivity: FunctionComponent = observer(() => { @@ -51,16 +64,16 @@ export const RecentActivity: FunctionComponent = observer(() => { hasNextPage: false, }; - const mergedActivity = [ + const mergedActivity: MergedActivity[] = [ ...transactions.map((tx) => ({ ...tx, - type: "transaction", + type: "transaction" as ActivityType, compareDate: new Date(tx.blockTimestamp), compareTxHash: tx.hash, })), ...recentTransfers.map((transfer) => ({ ...transfer, - type: "recentTransfer", + type: "recentTransfer" as ActivityType, compareDate: new Date(transfer.createdAtMs), compareTxHash: transfer.txHash, })), @@ -99,31 +112,38 @@ export const RecentActivity: FunctionComponent = observer(() => { ) : ( topActivity.map((activity) => { if (activity.type === "transaction") { + const recentTransactionActivity = + activity as FormattedTransaction & MergedActivityMetadata; + return ( @@ -131,6 +151,9 @@ export const RecentActivity: FunctionComponent = observer(() => { } if (activity.type === "recentTransfer") { + const recentTransferActivity = activity as RecentTransfer & + MergedActivityMetadata; + const getSimplifiedStatus = (status: TransferStatus) => { if (status === "success") return "success"; if (["refunded", "connection-error", "failed"].includes(status)) @@ -138,10 +161,12 @@ export const RecentActivity: FunctionComponent = observer(() => { return "pending"; }; - const simplifiedStatus = getSimplifiedStatus(activity.status); + const simplifiedStatus = getSimplifiedStatus( + recentTransferActivity.status + ); - const coinAmount = activity.amount.split(" ")[0]; - const coinDenom = activity.amount.split(" ")[1]; + const coinAmount = recentTransferActivity.amount.split(" ")[0]; + const coinDenom = recentTransferActivity.amount.split(" ")[1]; const asset = AssetLists.flatMap(({ assets }) => assets).find( ({ symbol }) => symbol === coinDenom ); @@ -150,28 +175,32 @@ export const RecentActivity: FunctionComponent = observer(() => { const currency = makeMinimalAsset(asset); - const pendingText = activity.isWithdraw + const pendingText = recentTransferActivity.isWithdraw ? t("assets.historyTable.pendingWithdraw") : t("assets.historyTable.pendingDeposit"); - const successText = activity.isWithdraw + const successText = recentTransferActivity.isWithdraw ? t("assets.historyTable.successWithdraw") : t("assets.historyTable.successDeposit"); - const failedText = activity.isWithdraw + const failedText = recentTransferActivity.isWithdraw ? t("assets.historyTable.failWithdraw") : t("assets.historyTable.failDeposit"); return ( Date: Wed, 7 Aug 2024 14:30:53 -0700 Subject: [PATCH 10/21] add loaders --- packages/web/components/assets/chain-logo.tsx | 25 +++- .../recent-activity-transaction-row.tsx | 120 +++++++++++------- .../recent-activity/recent-activity.tsx | 19 ++- .../transactions/use-recent-transfers.ts | 39 +++--- 4 files changed, 132 insertions(+), 71 deletions(-) diff --git a/packages/web/components/assets/chain-logo.tsx b/packages/web/components/assets/chain-logo.tsx index e76b1f7174..50b07ddc5c 100644 --- a/packages/web/components/assets/chain-logo.tsx +++ b/packages/web/components/assets/chain-logo.tsx @@ -2,14 +2,28 @@ import classNames from "classnames"; import { rgba } from "polished"; import { FunctionComponent } from "react"; +import { FallbackImg } from "~/components/assets/fallback-img"; interface ChainLogoProps { color: string | undefined; logoUri: string | undefined; prettyName?: string; - size?: "xs" | "sm" | "lg"; + size?: "xs" | "sm" | "md" | "lg"; className?: string; } +const getImageClasses = (size: ChainLogoProps["size"]) => { + switch (size) { + case "xs": + return "h-3 w-3"; + case "sm": + return "h-4 w-4"; + case "md": + return "h-5 w-5"; + default: + return "h-6 w-6"; + } +}; + export const ChainLogo: FunctionComponent = ({ color, logoUri, @@ -25,6 +39,7 @@ export const ChainLogo: FunctionComponent = ({ { xs: "h-4 w-4 rounded-sm", sm: "h-6 w-6 rounded-md", + md: "h-8 w-8 rounded-lg", lg: "h-12 w-12 rounded-xl", }[size], className @@ -34,13 +49,11 @@ export const ChainLogo: FunctionComponent = ({ }} > {logoUri && ( - {`${prettyName} )}
diff --git a/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx b/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx index d4ccd5b9c2..16cb21f9eb 100644 --- a/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx +++ b/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx @@ -3,15 +3,12 @@ import classNames from "classnames"; import { FunctionComponent } from "react"; import { FallbackImg, Icon } from "~/components/assets"; +import { ChainLogo } from "~/components/assets/chain-logo"; import { displayFiatPrice } from "~/components/transactions/transaction-utils"; import { useTranslation } from "~/hooks"; -import { theme } from "~/tailwind.config"; import { formatPretty } from "~/utils/formatter"; - -import { Spinner } from "../../loaders"; - export type TransactionStatus = "pending" | "success" | "failed"; - +import { api } from "~/utils/trpc"; type Effect = "swap" | "deposit" | "withdraw"; interface Transaction { @@ -66,70 +63,107 @@ interface Transaction { value?: PricePretty; }; onClick?: () => void; + toChainId?: string; + fromChainId?: string; } export const RecentActivityTransferRow: FunctionComponent = ({ status, - effect, title, transfer, + toChainId, + fromChainId, }) => { - const effectIconId = effect === "swap" ? "swap" : "down-arrow"; + const { data: chainData } = api.edge.chains.getChain.useQuery( + { + findChainNameOrId: fromChainId || "", + }, + { + useErrorBoundary: true, + } + ); + + console.log("direction: ", transfer?.direction); + console.log("chainData: ", chainData?.pretty_name); + console.log("-------------"); return (
-
- {status === "pending" ? ( - - ) : ( -
- {status === "success" ? ( - effect === "withdraw" ? ( - - ) : ( - - ) - ) : ( - - )} +
+

{title[status]}

+ {transfer && ( +
+ {transfer && formatPretty(transfer?.amount, { maxDecimals: 6 })}{" "} + from {chainData?.pretty_name}
)} -
-

{title[status]}

-
- {transfer && } + +
+ {transfer?.direction === "withdraw" ? ( + <> + + + + + ) : ( + <> + + + + + )} +
); }; export const RecentActivityTransactionRow: FunctionComponent = ({ status, - effect, title, caption, tokenConversion, transfer, }) => { - const effectIconId = effect === "swap" ? "swap" : "down-arrow"; - const { t } = useTranslation(); return (
@@ -161,7 +195,7 @@ export const RecentActivityTransactionRow: FunctionComponent = ({
{caption &&

{caption}

} {tokenConversion && ( - + )} {transfer && }
@@ -170,9 +204,7 @@ export const RecentActivityTransactionRow: FunctionComponent = ({ /** UI for displaying one token being converted into another by this transaction. */ const TokenConversion: FunctionComponent< - { status: TransactionStatus; effect: Effect } & NonNullable< - Transaction["tokenConversion"] - > + { status: TransactionStatus } & NonNullable > = ({ tokenIn, tokenOut }) => { return (
diff --git a/packages/web/components/transactions/recent-activity/recent-activity.tsx b/packages/web/components/transactions/recent-activity/recent-activity.tsx index cf88111ab2..c205216283 100644 --- a/packages/web/components/transactions/recent-activity/recent-activity.tsx +++ b/packages/web/components/transactions/recent-activity/recent-activity.tsx @@ -7,12 +7,12 @@ import { FunctionComponent } from "react"; import { LinkButton } from "~/components/buttons/link-button"; import { NoTransactionsSplash } from "~/components/transactions/no-transactions-splash"; +import { Skeleton } from "~/components/ui/skeleton"; import { AssetLists } from "~/config/generated/asset-lists"; import { useTranslation, useWalletSelect } from "~/hooks"; import { useStore } from "~/stores"; import { api } from "~/utils/trpc"; -import { Spinner } from "../../loaders"; import { RecentTransfer, useRecentTransfers } from "../use-recent-transfers"; import { RecentActivityTransactionRow, @@ -33,6 +33,19 @@ type MergedActivity = const ACTIVITY_LIMIT = 5; +const RecentActivitySkeleton = () => { + return ( +
+ {Array.from({ length: 5 }).map((_, index) => ( +
+ + +
+ ))} +
+ ); +}; + export const RecentActivity: FunctionComponent = observer(() => { const { accountStore } = useStore(); const { isLoading: isWalletLoading } = useWalletSelect(); @@ -106,7 +119,7 @@ export const RecentActivity: FunctionComponent = observer(() => {
{isLoading ? ( - + ) : topActivity?.length === 0 ? ( ) : ( @@ -187,6 +200,8 @@ export const RecentActivity: FunctionComponent = observer(() => { return ( ({ - txHash: key.startsWith("{") - ? (JSON.parse(key) as GetTransferStatusParams).sendTxHash - : key, - createdAtMs: createdAt.getTime(), - explorerUrl, - amount, - reason, - status, - isWithdraw, - }) + ({ key, explorerUrl, createdAt, amount, status, reason, isWithdraw }) => { + const parsedKey = key.startsWith("{") + ? (JSON.parse(key) as GetTransferStatusParams) + : null; + return { + txHash: parsedKey ? parsedKey.sendTxHash : key, + createdAtMs: createdAt.getTime(), + explorerUrl, + amount, + reason, + status, + isWithdraw, + toChainId: parsedKey ? parsedKey.toChainId : undefined, + fromChainId: parsedKey ? parsedKey.fromChainId : undefined, + }; + } ) .concat( ibcTransferHistoryStore @@ -105,6 +104,8 @@ export function useRecentTransfers(address?: string): RecentTransfer[] { isWithdraw: ChainIdHelper.parse(osmosisChainId).identifier !== ChainIdHelper.parse(destChainId).identifier, + toChainId: destChainId, + fromChainId: sourceChainId, }; }) ) From d40dc6d077fbe3179e1ff6e466605b6f9e34cfc0 Mon Sep 17 00:00:00 2001 From: Matt Upham <30577966+mattupham@users.noreply.github.com> Date: Wed, 7 Aug 2024 14:33:39 -0700 Subject: [PATCH 11/21] Add skeleton --- .../transactions/recent-activity/recent-activity.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/web/components/transactions/recent-activity/recent-activity.tsx b/packages/web/components/transactions/recent-activity/recent-activity.tsx index c205216283..1f9b6823d3 100644 --- a/packages/web/components/transactions/recent-activity/recent-activity.tsx +++ b/packages/web/components/transactions/recent-activity/recent-activity.tsx @@ -38,8 +38,8 @@ const RecentActivitySkeleton = () => {
{Array.from({ length: 5 }).map((_, index) => (
- - + +
))}
From 6d6be2cea9200840e2001882a9e047e2dc2d33ed Mon Sep 17 00:00:00 2001 From: Matt Upham <30577966+mattupham@users.noreply.github.com> Date: Wed, 7 Aug 2024 15:27:55 -0700 Subject: [PATCH 12/21] Clean up --- .../recent-activity-transaction-row.tsx | 156 +++++++----------- .../recent-activity/recent-activity.tsx | 9 +- 2 files changed, 63 insertions(+), 102 deletions(-) diff --git a/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx b/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx index 16cb21f9eb..ae392644da 100644 --- a/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx +++ b/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx @@ -11,33 +11,6 @@ export type TransactionStatus = "pending" | "success" | "failed"; import { api } from "~/utils/trpc"; type Effect = "swap" | "deposit" | "withdraw"; -interface Transaction { - isSelected?: boolean; - status: TransactionStatus; - /** At a high level- what this transaction does. */ - effect: Effect; - title: { - [key in TransactionStatus]: string; - }; - caption?: string; - tokenConversion?: { - tokenIn: { - amount: CoinPretty; - value?: PricePretty; - }; - tokenOut: { - amount: CoinPretty; - value?: PricePretty; - }; - }; - transfer?: { - direction: "deposit" | "withdraw"; - amount: CoinPretty; - value?: PricePretty; - }; - onClick?: () => void; -} - interface Transaction { isSelected?: boolean; status: TransactionStatus; @@ -67,16 +40,19 @@ interface Transaction { fromChainId?: string; } -export const RecentActivityTransferRow: FunctionComponent = ({ +export const TransferRow: FunctionComponent = ({ status, title, transfer, toChainId, fromChainId, }) => { + const findChainNameOrId = + transfer?.direction === "withdraw" ? toChainId : fromChainId; + const { data: chainData } = api.edge.chains.getChain.useQuery( { - findChainNameOrId: fromChainId || "", + findChainNameOrId: findChainNameOrId || "", }, { useErrorBoundary: true, @@ -84,9 +60,12 @@ export const RecentActivityTransferRow: FunctionComponent = ({ ); console.log("direction: ", transfer?.direction); - console.log("chainData: ", chainData?.pretty_name); + console.log("toChainId: ", toChainId); + console.log("fromChainId: ", fromChainId); console.log("-------------"); + const text = transfer?.direction === "withdraw" ? "to" : "from"; + return (
= ({ {transfer && (
{transfer && formatPretty(transfer?.amount, { maxDecimals: 6 })}{" "} - from {chainData?.pretty_name} + {text} {chainData?.pretty_name}
)}
@@ -152,7 +131,7 @@ export const RecentActivityTransferRow: FunctionComponent = ({ ); }; -export const RecentActivityTransactionRow: FunctionComponent = ({ +export const SwapRow: FunctionComponent = ({ status, title, caption, @@ -195,71 +174,56 @@ export const RecentActivityTransactionRow: FunctionComponent = ({
{caption &&

{caption}

} {tokenConversion && ( - +
+ + + +
+ )} + {transfer && ( +
+ +
+ {formatPretty(transfer.amount, { maxDecimals: 6 })} +
+ {transfer.value && ( +
+ {transfer.direction === "withdraw" ? "-" : "+"}{" "} + {transfer.value.symbol} + {Number(transfer.value.toDec().abs().toString()).toFixed(2)} +
+ )} +
)} - {transfer && } -
- ); -}; - -/** UI for displaying one token being converted into another by this transaction. */ -const TokenConversion: FunctionComponent< - { status: TransactionStatus } & NonNullable -> = ({ tokenIn, tokenOut }) => { - return ( -
- - -
); }; - -/** UI for displaying a token being deposited or withdrawn from Osmosis. */ -export const TokenTransfer: FunctionComponent< - { - status: TransactionStatus; - } & NonNullable -> = ({ status, direction, amount, value }) => ( -
- -
- {formatPretty(amount, { maxDecimals: 6 })} -
- {value && ( -
- {direction === "withdraw" ? "-" : "+"} {value.symbol} - {Number(value.toDec().abs().toString()).toFixed(2)} -
- )} -
-); diff --git a/packages/web/components/transactions/recent-activity/recent-activity.tsx b/packages/web/components/transactions/recent-activity/recent-activity.tsx index 1f9b6823d3..f2b2c1bb75 100644 --- a/packages/web/components/transactions/recent-activity/recent-activity.tsx +++ b/packages/web/components/transactions/recent-activity/recent-activity.tsx @@ -14,10 +14,7 @@ import { useStore } from "~/stores"; import { api } from "~/utils/trpc"; import { RecentTransfer, useRecentTransfers } from "../use-recent-transfers"; -import { - RecentActivityTransactionRow, - RecentActivityTransferRow, -} from "./recent-activity-transaction-row"; +import { SwapRow, TransferRow } from "./recent-activity-transaction-row"; type ActivityType = "transaction" | "recentTransfer"; @@ -129,7 +126,7 @@ export const RecentActivity: FunctionComponent = observer(() => { activity as FormattedTransaction & MergedActivityMetadata; return ( - { : t("assets.historyTable.failDeposit"); return ( - Date: Wed, 7 Aug 2024 15:33:57 -0700 Subject: [PATCH 13/21] Clean up --- .../recent-activity-transaction-row.tsx | 282 ++++++++---------- 1 file changed, 122 insertions(+), 160 deletions(-) diff --git a/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx b/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx index ae392644da..7acc5cc130 100644 --- a/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx +++ b/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx @@ -1,5 +1,4 @@ import { CoinPretty, PricePretty } from "@keplr-wallet/unit"; -import classNames from "classnames"; import { FunctionComponent } from "react"; import { FallbackImg, Icon } from "~/components/assets"; @@ -7,19 +6,18 @@ import { ChainLogo } from "~/components/assets/chain-logo"; import { displayFiatPrice } from "~/components/transactions/transaction-utils"; import { useTranslation } from "~/hooks"; import { formatPretty } from "~/utils/formatter"; -export type TransactionStatus = "pending" | "success" | "failed"; import { api } from "~/utils/trpc"; + +export type TransactionStatus = "pending" | "success" | "failed"; type Effect = "swap" | "deposit" | "withdraw"; -interface Transaction { +interface Activity { isSelected?: boolean; status: TransactionStatus; - /** At a high level- what this transaction does. */ effect: Effect; title: { [key in TransactionStatus]: string; }; - caption?: string; tokenConversion?: { tokenIn: { amount: CoinPretty; @@ -35,12 +33,28 @@ interface Transaction { amount: CoinPretty; value?: PricePretty; }; - onClick?: () => void; toChainId?: string; fromChainId?: string; } -export const TransferRow: FunctionComponent = ({ +export const RecentActivityRow: FunctionComponent<{ + status: TransactionStatus; + title: { [key in TransactionStatus]: string }; + leftComponent: JSX.Element | null; + rightComponent: JSX.Element | null; +}> = ({ status, title, leftComponent, rightComponent }) => { + return ( +
+
+

{title[status]}

+ {leftComponent} +
+
{rightComponent}
+
+ ); +}; + +export const TransferRow: FunctionComponent = ({ status, title, transfer, @@ -59,171 +73,119 @@ export const TransferRow: FunctionComponent = ({ } ); - console.log("direction: ", transfer?.direction); - console.log("toChainId: ", toChainId); - console.log("fromChainId: ", fromChainId); - console.log("-------------"); - const text = transfer?.direction === "withdraw" ? "to" : "from"; - return ( -
-
-

{title[status]}

- {transfer && ( -
- {transfer && formatPretty(transfer?.amount, { maxDecimals: 6 })}{" "} - {text} {chainData?.pretty_name} -
- )} -
- -
- {transfer?.direction === "withdraw" ? ( - <> - - - - - ) : ( - <> - - - - - )} -
+ const leftComponent = transfer ? ( +
+ {formatPretty(transfer.amount, { maxDecimals: 6 })} {text}{" "} + {chainData?.pretty_name}
+ ) : null; + + const rightComponent = + transfer?.direction === "withdraw" ? ( + <> + + + + + ) : ( + <> + + + + + ); + + return ( + ); }; -export const SwapRow: FunctionComponent = ({ +export const SwapRow: FunctionComponent = ({ status, title, - caption, tokenConversion, - transfer, }) => { const { t } = useTranslation(); - return ( -
-
-
-
-

{title[status]}

- {tokenConversion && ( -
- {displayFiatPrice(tokenConversion.tokenIn?.value, "", t)}{" "} - {tokenConversion.tokenOut.amount.denom}{" "} - {" "} - {tokenConversion.tokenIn.amount.denom} -
- )} -
- {tokenConversion && ( -
- {formatPretty(tokenConversion.tokenOut.amount, { - maxDecimals: 6, - })} - -
- )} -
-
- {caption &&

{caption}

} - {tokenConversion && ( -
- - - -
- )} - {transfer && ( -
- -
- {formatPretty(transfer.amount, { maxDecimals: 6 })} -
- {transfer.value && ( -
- {transfer.direction === "withdraw" ? "-" : "+"}{" "} - {transfer.value.symbol} - {Number(transfer.value.toDec().abs().toString()).toFixed(2)} -
- )} -
- )} + const leftComponent = tokenConversion ? ( +
+ {displayFiatPrice(tokenConversion.tokenIn?.value, "", t)}{" "} + {tokenConversion.tokenOut.amount.denom}{" "} + {" "} + {tokenConversion.tokenIn.amount.denom}
+ ) : null; + + const rightComponent = tokenConversion ? ( +
+ + + +
+ ) : null; + + return ( + ); }; From be567eb99546bc10534f1231a89701b80588326c Mon Sep 17 00:00:00 2001 From: Matt Upham <30577966+mattupham@users.noreply.github.com> Date: Wed, 7 Aug 2024 15:35:58 -0700 Subject: [PATCH 14/21] Update types --- .../web/components/transactions/use-recent-transfers.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/web/components/transactions/use-recent-transfers.ts b/packages/web/components/transactions/use-recent-transfers.ts index 4b4e0b222d..79bf0dde3f 100644 --- a/packages/web/components/transactions/use-recent-transfers.ts +++ b/packages/web/components/transactions/use-recent-transfers.ts @@ -18,8 +18,8 @@ export type RecentTransfer = { reason?: TransferFailureReason; status: TransferStatus; isWithdraw: boolean; - toChainId?: string; - fromChainId?: string; + toChainId?: string | number; + fromChainId?: string | number; }; const osmosisChainId = ChainList[0].chain_id; @@ -32,11 +32,6 @@ export function useRecentTransfers(address?: string): RecentTransfer[] { return []; } - console.log( - "transferHistoryStore .getHistoriesByAccount(address): ", - transferHistoryStore.getHistoriesByAccount(address) - ); - // reconcile histories from IBC and non-IBC history stores return transferHistoryStore .getHistoriesByAccount(address) From eadf88ef1e66b0a8e89fdc08f4517113c84434a4 Mon Sep 17 00:00:00 2001 From: Matt Upham <30577966+mattupham@users.noreply.github.com> Date: Wed, 7 Aug 2024 17:16:39 -0700 Subject: [PATCH 15/21] Add fetch network details --- packages/trpc/src/chains.ts | 76 ++++++++++++++++++- packages/utils/src/bitcoin.ts | 1 + packages/utils/src/solana.ts | 1 + .../recent-activity-transaction-row.tsx | 22 +++--- .../transactions/use-recent-transfers.ts | 9 +++ 5 files changed, 98 insertions(+), 11 deletions(-) diff --git a/packages/trpc/src/chains.ts b/packages/trpc/src/chains.ts index 717928e648..41e11c954e 100644 --- a/packages/trpc/src/chains.ts +++ b/packages/trpc/src/chains.ts @@ -1,5 +1,9 @@ import { getChain } from "@osmosis-labs/server"; -import { EthereumChainInfo } from "@osmosis-labs/utils"; +import { + BitcoinChainInfo, + EthereumChainInfo, + SolanaChainInfo, +} from "@osmosis-labs/utils"; import { z } from "zod"; import { createTRPCRouter, publicProcedure } from "./api"; @@ -27,4 +31,74 @@ export const chainsRouter = createTRPCRouter({ .query(({ input: { chainId } }) => Object.values(EthereumChainInfo).find((chain) => chain.id === chainId) ), + getChainDisplayInfo: publicProcedure + .input( + z.object({ + chainId: z.union([z.string(), z.number()]), + }) + ) + .query( + ({ + input: { chainId }, + ctx, + }): + | { + chainId: string | number; + prettyName: string; + relativeLogoUrl?: string; + color?: string; + } + | undefined => { + // cosmos chains + try { + const cosmosChain = getChain({ + ...ctx, + chainNameOrId: String(chainId), + }); + + return { + chainId: cosmosChain.chain_id, + prettyName: cosmosChain.pretty_name, + relativeLogoUrl: cosmosChain?.logoURIs?.svg, + color: cosmosChain?.logoURIs?.theme?.background_color_hex, + }; + } catch (error) { + // if cosmos chain is undefined, check evm chains + const evmChain = Object.values(EthereumChainInfo).find( + (chain) => chain.id === chainId + ); + + if (evmChain) { + return { + chainId: evmChain.id, + prettyName: evmChain.chainName, + relativeLogoUrl: evmChain.relativeLogoUrl, + color: evmChain.color, + }; + } + + const bitcoinChain = + BitcoinChainInfo.chainId === chainId ? BitcoinChainInfo : undefined; + if (bitcoinChain) { + return { + chainId: bitcoinChain.chainId, + prettyName: bitcoinChain.prettyName, + relativeLogoUrl: bitcoinChain.relativeLogoUrl, + color: bitcoinChain.color, + }; + } + + const solanaChain = + SolanaChainInfo.chainId === chainId ? SolanaChainInfo : undefined; + if (solanaChain) { + return { + chainId: solanaChain.chainId, + prettyName: solanaChain.prettyName, + relativeLogoUrl: solanaChain.relativeLogoUrl, + color: solanaChain.color, + }; + } + } + } + ), }); diff --git a/packages/utils/src/bitcoin.ts b/packages/utils/src/bitcoin.ts index d66e0a8239..7a0920e56d 100644 --- a/packages/utils/src/bitcoin.ts +++ b/packages/utils/src/bitcoin.ts @@ -3,4 +3,5 @@ export const BitcoinChainInfo = { chainId: "bitcoin", chainName: "Bitcoin", color: "#F7931A", + relativeLogoUrl: "/networks/bitcoin.svg", }; diff --git a/packages/utils/src/solana.ts b/packages/utils/src/solana.ts index f41193e9c1..d0a79dfc5e 100644 --- a/packages/utils/src/solana.ts +++ b/packages/utils/src/solana.ts @@ -3,4 +3,5 @@ export const SolanaChainInfo = { chainId: "solana", chainName: "Solana", color: "#9945FF", + relativeLogoUrl: "/networks/solana.svg", }; diff --git a/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx b/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx index 7acc5cc130..57d12499c4 100644 --- a/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx +++ b/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx @@ -33,8 +33,8 @@ interface Activity { amount: CoinPretty; value?: PricePretty; }; - toChainId?: string; - fromChainId?: string; + toChainId?: string | number; + fromChainId?: string | number; } export const RecentActivityRow: FunctionComponent<{ @@ -64,21 +64,23 @@ export const TransferRow: FunctionComponent = ({ const findChainNameOrId = transfer?.direction === "withdraw" ? toChainId : fromChainId; - const { data: chainData } = api.edge.chains.getChain.useQuery( + const { data: chainData } = api.edge.chains.getChainDisplayInfo.useQuery( { - findChainNameOrId: findChainNameOrId || "", + chainId: "bitcoin", }, { - useErrorBoundary: true, + useErrorBoundary: false, } ); + // console.log("chainDataEVM: ", chainDataEVM); + const text = transfer?.direction === "withdraw" ? "to" : "from"; const leftComponent = transfer ? (
{formatPretty(transfer.amount, { maxDecimals: 6 })} {text}{" "} - {chainData?.pretty_name} + {chainData?.prettyName}
) : null; @@ -99,18 +101,18 @@ export const TransferRow: FunctionComponent = ({ className="my-[8px] mx-[4px] text-osmoverse-500" /> ) : ( <> Date: Wed, 7 Aug 2024 17:59:43 -0700 Subject: [PATCH 16/21] Clean up chain id --- .../recent-activity-transaction-row.tsx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx b/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx index 57d12499c4..064bdd0a7d 100644 --- a/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx +++ b/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx @@ -61,20 +61,18 @@ export const TransferRow: FunctionComponent = ({ toChainId, fromChainId, }) => { - const findChainNameOrId = - transfer?.direction === "withdraw" ? toChainId : fromChainId; + const chainId = + (transfer?.direction === "withdraw" ? toChainId : fromChainId) || ""; const { data: chainData } = api.edge.chains.getChainDisplayInfo.useQuery( { - chainId: "bitcoin", + chainId, }, { useErrorBoundary: false, } ); - // console.log("chainDataEVM: ", chainDataEVM); - const text = transfer?.direction === "withdraw" ? "to" : "from"; const leftComponent = transfer ? ( @@ -102,7 +100,7 @@ export const TransferRow: FunctionComponent = ({ /> @@ -111,7 +109,7 @@ export const TransferRow: FunctionComponent = ({ <> From da506503635b3065c3c47fcc32fd7c07f2522886 Mon Sep 17 00:00:00 2001 From: Matt Upham <30577966+mattupham@users.noreply.github.com> Date: Wed, 7 Aug 2024 18:01:23 -0700 Subject: [PATCH 17/21] add en translation --- .../recent-activity/recent-activity-transaction-row.tsx | 7 ++++++- .../transactions/recent-activity/recent-activity.tsx | 2 -- packages/web/localizations/en.json | 4 +++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx b/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx index 064bdd0a7d..58c9af4e37 100644 --- a/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx +++ b/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx @@ -61,6 +61,8 @@ export const TransferRow: FunctionComponent = ({ toChainId, fromChainId, }) => { + const { t } = useTranslation(); + const chainId = (transfer?.direction === "withdraw" ? toChainId : fromChainId) || ""; @@ -73,7 +75,10 @@ export const TransferRow: FunctionComponent = ({ } ); - const text = transfer?.direction === "withdraw" ? "to" : "from"; + const text = + transfer?.direction === "withdraw" + ? t("portfolio.to") + : t("portfolio.from"); const leftComponent = transfer ? (
diff --git a/packages/web/components/transactions/recent-activity/recent-activity.tsx b/packages/web/components/transactions/recent-activity/recent-activity.tsx index f2b2c1bb75..edd753fdf4 100644 --- a/packages/web/components/transactions/recent-activity/recent-activity.tsx +++ b/packages/web/components/transactions/recent-activity/recent-activity.tsx @@ -53,8 +53,6 @@ export const RecentActivity: FunctionComponent = observer(() => { const recentTransfers = useRecentTransfers(wallet?.address); - console.log("Recent Transfers: ", recentTransfers); - const { data: transactionsData, isFetching: isGetTransactionsFetching } = api.edge.transactions.getTransactions.useQuery( { diff --git a/packages/web/localizations/en.json b/packages/web/localizations/en.json index 1cccae2951..9d8a432a2e 100644 --- a/packages/web/localizations/en.json +++ b/packages/web/localizations/en.json @@ -328,7 +328,9 @@ "all": "All", "assets": "Assets", "recentActivity": "Recent activity", - "seeAll": "See all" + "seeAll": "See all", + "to": "to", + "from": "from" }, "buyTokens": "Buy tokens", "components": { From 62bef53d163e82a99bc2b86b3dd23e37ab3b04c0 Mon Sep 17 00:00:00 2001 From: Matt Upham <30577966+mattupham@users.noreply.github.com> Date: Wed, 7 Aug 2024 18:06:46 -0700 Subject: [PATCH 18/21] Clean up --- .../recent-activity-transaction-row.tsx | 77 ++++++++----------- 1 file changed, 30 insertions(+), 47 deletions(-) diff --git a/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx b/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx index 58c9af4e37..ae306225f0 100644 --- a/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx +++ b/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx @@ -87,59 +87,42 @@ export const TransferRow: FunctionComponent = ({
) : null; - const rightComponent = - transfer?.direction === "withdraw" ? ( - <> - - - - - ) : ( - <> - - - - - ); + const rightComponent = [ + , + , + , + ]; + + const orderedRightComponent = + transfer?.direction === "withdraw" + ? rightComponent + : rightComponent.reverse(); return ( {orderedRightComponent}} /> ); }; From 58455556302857c8cb836c9734bd44e5206dee98 Mon Sep 17 00:00:00 2001 From: Matt Upham <30577966+mattupham@users.noreply.github.com> Date: Wed, 7 Aug 2024 18:09:24 -0700 Subject: [PATCH 19/21] Fix button --- packages/trpc/src/chains.ts | 2 ++ .../components/transactions/recent-activity/recent-activity.tsx | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/trpc/src/chains.ts b/packages/trpc/src/chains.ts index 41e11c954e..6b4038bb38 100644 --- a/packages/trpc/src/chains.ts +++ b/packages/trpc/src/chains.ts @@ -98,6 +98,8 @@ export const chainsRouter = createTRPCRouter({ color: solanaChain.color, }; } + + throw new Error(`Chain with ID ${chainId} not found`); } } ), diff --git a/packages/web/components/transactions/recent-activity/recent-activity.tsx b/packages/web/components/transactions/recent-activity/recent-activity.tsx index edd753fdf4..a42d98aa61 100644 --- a/packages/web/components/transactions/recent-activity/recent-activity.tsx +++ b/packages/web/components/transactions/recent-activity/recent-activity.tsx @@ -109,7 +109,7 @@ export const RecentActivity: FunctionComponent = observer(() => { className="text-osmoverse-400" label={t("portfolio.seeAll")} ariaLabel={t("portfolio.seeAll")} - size="sm" + size="md" />
From 49619b1c34ea497973c2899bfcee90c0498fd403 Mon Sep 17 00:00:00 2001 From: Matt Upham <30577966+mattupham@users.noreply.github.com> Date: Wed, 7 Aug 2024 18:12:15 -0700 Subject: [PATCH 20/21] Remove logs --- .../web/components/transactions/use-recent-transfers.ts | 9 --------- 1 file changed, 9 deletions(-) diff --git a/packages/web/components/transactions/use-recent-transfers.ts b/packages/web/components/transactions/use-recent-transfers.ts index fa6ad09155..79bf0dde3f 100644 --- a/packages/web/components/transactions/use-recent-transfers.ts +++ b/packages/web/components/transactions/use-recent-transfers.ts @@ -32,15 +32,6 @@ export function useRecentTransfers(address?: string): RecentTransfer[] { return []; } - console.log( - "Transfer History Store: ", - transferHistoryStore.getHistoriesByAccount(address) - ); - console.log( - "IBC Transfer History Store: ", - ibcTransferHistoryStore.getHistoriesAndUncommitedHistoriesByAccount(address) - ); - // reconcile histories from IBC and non-IBC history stores return transferHistoryStore .getHistoriesByAccount(address) From b2348e59d6d0e329bf6edbc867ca0d237f824ca6 Mon Sep 17 00:00:00 2001 From: Matt Upham <30577966+mattupham@users.noreply.github.com> Date: Wed, 7 Aug 2024 18:15:19 -0700 Subject: [PATCH 21/21] Update recent activity --- .../recent-activity-transaction-row.tsx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx b/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx index ae306225f0..645c476378 100644 --- a/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx +++ b/packages/web/components/transactions/recent-activity/recent-activity-transaction-row.tsx @@ -87,7 +87,7 @@ export const TransferRow: FunctionComponent = ({
) : null; - const rightComponent = [ + const rightComponentList = [ = ({ />, ]; - const orderedRightComponent = - transfer?.direction === "withdraw" - ? rightComponent - : rightComponent.reverse(); + const rightComponent = ( + <> + {transfer?.direction === "withdraw" + ? rightComponentList + : rightComponentList.reverse()} + + ); return ( {orderedRightComponent}} + rightComponent={rightComponent} /> ); };