diff --git a/apps/watcher/app/_constants/index.ts b/apps/watcher/app/_constants/index.ts new file mode 100644 index 00000000..5860d39c --- /dev/null +++ b/apps/watcher/app/_constants/index.ts @@ -0,0 +1,3 @@ +export const CARDANO_BASE_TX_URL = 'https://cardanoscan.io/transaction/'; +export const ERGO_BASE_TX_URL = + 'https://explorer.ergoplatform.com/transactions/'; diff --git a/apps/watcher/app/_mock/mockedData.ts b/apps/watcher/app/_mock/mockedData.ts index 9d9b32c6..a5c4e23e 100644 --- a/apps/watcher/app/_mock/mockedData.ts +++ b/apps/watcher/app/_mock/mockedData.ts @@ -269,6 +269,22 @@ const generateRevenueRecords = (numberOfRecords: number) => { height: 100, timestamp: Date.now(), status: 'Done', + revenues: [ + { + tokenId: + '6c1526b2a5ef010edb622719d9d7fbde8437a39543547c3effbe72ad33504cf1', + amount: 1000, + name: 'fakeRSN', + decimals: 0, + }, + { + tokenId: + '6c1526b2a5ef010edb622719d9d7fbde8437a39543547c3effbe72ad33504cf2', + amount: 100, + name: 'awesome token', + decimals: 2, + }, + ], })); }; diff --git a/apps/watcher/app/_types/api.ts b/apps/watcher/app/_types/api.ts index d350895e..261e3e4e 100644 --- a/apps/watcher/app/_types/api.ts +++ b/apps/watcher/app/_types/api.ts @@ -86,6 +86,7 @@ export interface Revenue { height: number; timestamp: number; status: string; + revenues: TokenInfo[]; } export type ApiRevenueResponse = Paginated; diff --git a/apps/watcher/app/events/TableRow.tsx b/apps/watcher/app/events/TableRow.tsx index a964e8f3..d9e6ad1b 100644 --- a/apps/watcher/app/events/TableRow.tsx +++ b/apps/watcher/app/events/TableRow.tsx @@ -1,11 +1,18 @@ import { useState, FC, useMemo } from 'react'; -import { Button, EnhancedTableCell, TableRow } from '@rosen-bridge/ui-kit'; +import { + Button, + EnhancedTableCell, + Link, + TableRow, +} from '@rosen-bridge/ui-kit'; import { AngleDown, AngleUp } from '@rosen-bridge/icons'; import { Event } from '@rosen-ui/types'; +import { CARDANO_BASE_TX_URL, ERGO_BASE_TX_URL } from '@/_constants'; + interface RowProps extends Event { isLoading?: boolean; } @@ -27,19 +34,31 @@ export const mobileHeader = [ export const tabletHeader = [ { - title: 'ID', + title: 'Tx Id', + cellProps: { + width: 150, + }, + }, + { + title: 'Token Id', + cellProps: { + width: 150, + }, + }, + { + title: 'From Address', cellProps: { width: 150, }, }, { - title: 'From', + title: 'To Address', cellProps: { - width: 250, + width: 150, }, }, { - title: 'To', + title: 'Height', cellProps: { width: 150, }, @@ -48,50 +67,112 @@ export const tabletHeader = [ title: 'Amount', cellProps: { width: 150, - align: 'right' as const, + }, + }, + { + title: 'Bridge Fee', + cellProps: { + width: 150, + }, + }, + { + title: 'Network Fee', + cellProps: { + width: 150, + }, + }, + { + title: 'Event Id', + cellProps: { + width: 150, + }, + }, + { + title: 'Reports', + cellProps: { + width: 150, + }, + }, + { + title: 'Status', + cellProps: { + width: 150, }, }, ]; -const renderValue = (value?: string | number | undefined) => { - return value || '-'; -}; - export const MobileRow: FC = (props) => { const { isLoading, ...row } = props; const [expand, setExpand] = useState(false); const rowStyles = useMemo( () => (isLoading ? { opacity: 0.3 } : {}), - [isLoading] + [isLoading], ); const toggleExpand = () => { setExpand((prevState) => !prevState); }; + const baseTxUrl = + row.fromChain === 'ergo' ? ERGO_BASE_TX_URL : CARDANO_BASE_TX_URL; + return ( <> - - Id - {row.eventId} - - - - From chain + + Tx Id + + + {row.sourceTxId.slice(0, 8)} + - {row.fromChain} - - To chain - {row.toChain} + + Token Id + + {row.sourceChainTokenId.slice(0, 8)} + {expand && ( <> + + From Address + {row.fromAddress.slice(0, 8)} + + + To Address + {row.toAddress.slice(0, 8)} + + + Height + {row.height} + Amount {row.amount} + + Bridge Fee + {row.bridgeFee} + + + Network Fee + {row.networkFee} + + + Event Id + {row.eventId.slice(0, 8)} + + + Reports + {row.WIDs.split(',').length} + + + Status + + {row.spendBlock ? 'Completed' : 'Incomplete'} + + )} @@ -113,12 +194,36 @@ export const MobileRow: FC = (props) => { export const TabletRow: FC = (props) => { const { isLoading, ...row } = props; + + const baseTxUrl = + row.fromChain === 'ergo' ? ERGO_BASE_TX_URL : CARDANO_BASE_TX_URL; + return ( - {row.eventId} - {row.fromChain} - {row.toChain} - {row.amount} + + + {row.sourceTxId.slice(0, 8)} + + + + {row.sourceChainTokenId.slice(0, 8)} + + {row.fromAddress.slice(0, 8)} + {row.toAddress.slice(0, 8)} + {row.height} + {row.amount} + {row.bridgeFee} + {row.networkFee} + {row.eventId.slice(0, 8)} + {row.WIDs.split(',').length} + + {row.spendBlock ? 'Completed' : 'Incomplete'} + ); }; diff --git a/apps/watcher/app/observations/TableRow.tsx b/apps/watcher/app/observations/TableRow.tsx index 05b48741..717cef1a 100644 --- a/apps/watcher/app/observations/TableRow.tsx +++ b/apps/watcher/app/observations/TableRow.tsx @@ -1,9 +1,16 @@ import { useState, FC, useMemo } from 'react'; -import { Button, EnhancedTableCell, TableRow } from '@rosen-bridge/ui-kit'; +import { + Button, + EnhancedTableCell, + Link, + TableRow, +} from '@rosen-bridge/ui-kit'; import { AngleDown, AngleUp } from '@rosen-bridge/icons'; +import { CARDANO_BASE_TX_URL, ERGO_BASE_TX_URL } from '@/_constants'; + import { Observation } from '@/_types/api'; interface RowProps extends Observation { @@ -27,28 +34,27 @@ export const mobileHeader = [ export const tabletHeader = [ { - title: 'ID', + title: 'Tx Id', cellProps: { - width: 50, + width: 150, }, }, { - title: 'From', + title: 'Token Id', cellProps: { - width: 250, + width: 150, }, }, { - title: 'To', + title: 'From Address', cellProps: { width: 150, }, }, { - title: 'Amount', + title: 'To Address', cellProps: { width: 150, - align: 'right' as const, }, }, { @@ -58,69 +64,92 @@ export const tabletHeader = [ }, }, { - title: 'Network', + title: 'Amount', + cellProps: { + width: 150, + }, + }, + { + title: 'Bridge Fee', + cellProps: { + width: 150, + }, + }, + { + title: 'Network Fee', cellProps: { width: 150, }, }, { - title: 'Bridge', + title: 'Event Id', cellProps: { width: 150, }, }, ]; -const renderValue = (value?: string | number | undefined) => { - return value || '-'; -}; - export const MobileRow: FC = (props) => { const { isLoading, ...row } = props; const [expand, setExpand] = useState(false); const rowStyles = useMemo( () => (isLoading ? { opacity: 0.3 } : {}), - [isLoading] + [isLoading], ); const toggleExpand = () => { setExpand((prevState) => !prevState); }; + const baseTxUrl = + row.fromChain === 'ergo' ? ERGO_BASE_TX_URL : CARDANO_BASE_TX_URL; + return ( <> - - Id - {row.id} - - - - From chain + + Tx Id + + + {row.sourceTxId.slice(0, 8)} + - {row.fromChain} - - To chain - {row.toChain} + + Token Id + + {row.sourceChainTokenId.slice(0, 8)} + {expand && ( <> + + From Address + {row.fromAddress.slice(0, 8)} + + + To Address + {row.toAddress.slice(0, 8)} + + + Height + {row.height} + Amount {row.amount} - Height - {renderValue(row.height)} + Bridge Fee + {row.bridgeFee} - Network fee - {renderValue(row.networkFee)} + Network Fee + {row.networkFee} - Bridge fee - {renderValue(row.bridgeFee)} + Event Id + {row.requestId.slice(0, 8)} )} @@ -143,15 +172,32 @@ export const MobileRow: FC = (props) => { export const TabletRow: FC = (props) => { const { isLoading, ...row } = props; + + const baseTxUrl = + row.fromChain === 'ergo' ? ERGO_BASE_TX_URL : CARDANO_BASE_TX_URL; + return ( - {row.id} - {row.fromChain} - {row.toChain} - {row.amount} - {renderValue(row.height)} - {renderValue(row.networkFee)} - {renderValue(row.bridgeFee)} + + + {row.sourceTxId.slice(0, 8)} + + + + {row.sourceChainTokenId.slice(0, 8)} + + {row.fromAddress.slice(0, 8)} + {row.toAddress.slice(0, 8)} + {row.height} + {row.amount} + {row.bridgeFee} + {row.networkFee} + {row.requestId.slice(0, 8)} ); }; diff --git a/apps/watcher/app/revenues/TableRow.tsx b/apps/watcher/app/revenues/TableRow.tsx index be83cc8c..16c4414a 100644 --- a/apps/watcher/app/revenues/TableRow.tsx +++ b/apps/watcher/app/revenues/TableRow.tsx @@ -4,6 +4,8 @@ import { Button, EnhancedTableCell, TableRow } from '@rosen-bridge/ui-kit'; import { AngleDown, AngleUp } from '@rosen-bridge/icons'; +import useRsnToken from '@/_hooks/useRsnToken'; + import { Revenue } from '@/_types/api'; interface RowProps extends Revenue { @@ -27,61 +29,42 @@ export const mobileHeader = [ export const tabletHeader = [ { - title: 'ID', - cellProps: { - width: 50, - }, - }, - { - title: 'From Chain', - cellProps: { - width: 250, - }, - }, - { - title: 'To Chain', + title: 'Event Id', cellProps: { width: 150, }, }, { - title: 'Amount', + title: 'Token Id', cellProps: { width: 150, - align: 'right' as const, }, }, { - title: 'Height', + title: 'RSN Income', cellProps: { width: 150, }, }, { - title: 'Network fee', - cellProps: { - width: 150, - }, - }, - { - title: 'Bridge fee', + title: 'Token Income', cellProps: { width: 150, }, }, ]; -const renderValue = (value?: string | number | undefined) => { - return value || '-'; -}; - export const MobileRow: FC = (props) => { - const { isLoading, ...row } = props; + const { isLoading: isLoadingProp, ...row } = props; const [expand, setExpand] = useState(false); + const { rsnToken, isLoading: isRsnTokenLoading } = useRsnToken(); + + const isLoading = isLoadingProp || isRsnTokenLoading; + const rowStyles = useMemo( () => (isLoading ? { opacity: 0.3 } : {}), - [isLoading] + [isLoading], ); const toggleExpand = () => { @@ -90,37 +73,31 @@ export const MobileRow: FC = (props) => { return ( <> - - Id - {row.id} - - - - From chain - - {row.fromChain} + + Event Id + {row.eventId.slice(0, 8)} - - To chain - {row.toChain} + + Token Id + {row.tokenId.slice(0, 8)} {expand && ( <> - - Amount - {row.amount} - - - Height - {renderValue(row.height)} - - Network fee - {renderValue(row.networkFee)} + RSN Income + + {row.revenues.find((token) => token.tokenId === rsnToken?.tokenId) + ?.amount ?? 0} + - Bridge fee - {renderValue(row.bridgeFee)} + Token Income + + {row.revenues + .filter((token) => token.tokenId !== rsnToken?.tokenId) + .map((token) => `${token.amount}${token.name}`) + .join('+')} + )} @@ -142,16 +119,28 @@ export const MobileRow: FC = (props) => { }; export const TabletRow: FC = (props) => { - const { isLoading, ...row } = props; + const { isLoading: isLoadingProp, ...row } = props; + + const { rsnToken, isLoading: isRsnTokenLoading } = useRsnToken(); + + const isLoading = isLoadingProp || isRsnTokenLoading; + + console.warn(rsnToken?.tokenId); + return ( - {row.id} - {row.fromChain} - {row.toChain} - {row.amount} - {renderValue(row.height)} - {renderValue(row.networkFee)} - {renderValue(row.bridgeFee)} + {row.eventId.slice(0, 8)} + {row.tokenId.slice(0, 8)} + + {row.revenues.find((token) => token.tokenId === rsnToken?.tokenId) + ?.amount ?? 0} + + + {row.revenues + .filter((token) => token.tokenId !== rsnToken?.tokenId) + .map((token) => `${token.amount} ${token.name ?? 'unnamed'}`) + .join(' + ')} + ); };