Skip to content

Commit

Permalink
Merge branch 'display-tx' into 'dev'
Browse files Browse the repository at this point in the history
complete transaction page

See merge request ergo/minotaur/minotaur-wallet!36
  • Loading branch information
vorujack committed Sep 6, 2024
2 parents 80ab11f + b57188a commit ffbedf9
Show file tree
Hide file tree
Showing 13 changed files with 222 additions and 65 deletions.
6 changes: 5 additions & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
image: node:16.17
image: node:20.12

stages:
- installation
Expand All @@ -13,6 +13,7 @@ installation:
policy: push
paths:
- node_modules
- apps/wallet/node_modules
script:
- npm ci

Expand All @@ -23,6 +24,7 @@ type_check:
policy: pull
paths:
- node_modules
- apps/wallet/node_modules
script:
- npm run type-check

Expand All @@ -33,6 +35,7 @@ lint:
policy: pull
paths:
- node_modules
- apps/wallet/node_modules
script:
- npm run lint

Expand All @@ -43,6 +46,7 @@ test:
policy: pull
paths:
- node_modules
- apps/wallet/node_modules
script:
- npm run coverage
coverage: '/All files[^|]*\|[^|]*\s+([\d\.]+)/'
Expand Down
2 changes: 1 addition & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged
#npx lint-staged
2 changes: 1 addition & 1 deletion apps/wallet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"capacitor-plugin-safe-area": "^2.0.6",
"clipboardy": "^4.0.0",
"crypto-js": "^4.2.0",
"ergo-lib-wasm-browser": "^0.26.0",
"ergo-lib-wasm-browser": "^0.28.0",
"generate-password": "^1.7.1",
"is-electron": "^2.2.2",
"json-bigint": "^1.0.0",
Expand Down
108 changes: 108 additions & 0 deletions apps/wallet/src/components/tx/TxDisplay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { openTxInBrowser } from '@/action/tx';
import ErgAmount from '@/components/amounts-display/ErgAmount';
import IssuedBurntTokenAmount from '@/components/token-amount/IssuedBurntTokenAmount';
import useIssuedAndBurntTokens from '@/hooks/useIssuedAndBurntTokens';
import useTxValues from '@/hooks/useTxValues';
import TxAssetDetail from '@/pages/wallet-page/transaction/TxAssetDetail';
import { StateWallet } from '@/store/reducer/wallet';
import { getValueColor } from '@/utils/functions';
import { OpenInNew } from '@mui/icons-material';
import { IconButton, Stack, Typography } from '@mui/material';
import React from 'react';
import * as wasm from 'ergo-lib-wasm-browser';

interface TxDisplayPropsType {
wallet: StateWallet;
tx: wasm.Transaction | wasm.UnsignedTransaction;
boxes: Array<wasm.ErgoBox>;
date?: string;
}

const TxDisplay = ({ tx, boxes, wallet, date }: TxDisplayPropsType) => {
const txId = tx.id().to_str();
const issuedAndBurnt = useIssuedAndBurntTokens(tx, boxes);
const { txValues } = useTxValues(tx, boxes, wallet);
const openTx = () => openTxInBrowser(wallet.networkType, txId ?? '');
return (
<React.Fragment>
<Typography
fontSize="2rem"
textAlign="center"
color={getValueColor(-txValues.total)}
mb={2}
>
<ErgAmount
amount={txValues.total > 0 ? txValues.total : -txValues.total}
/>
<Typography component="span" ml={1}>
ERG
</Typography>
</Typography>
{date ? (
<React.Fragment>
<Typography variant="body2" color="textSecondary">
Received on
</Typography>
<Typography mb={2}>{date}</Typography>
</React.Fragment>
) : null}
<div>
<Typography variant="body2" color="textSecondary">
Transaction Id
</Typography>
<Typography mb={2} sx={{ overflowWrap: 'anywhere' }} onClick={openTx}>
{txId}
<IconButton size="small">
<OpenInNew />
</IconButton>
</Typography>
</div>
{Object.entries(txValues.tokens).map((item) => (
<TxAssetDetail
amount={-item[1]}
id={item[0]}
networkType={wallet.networkType}
key={item[0]}
/>
))}
{issuedAndBurnt.burnt.length > 0 ? (
<React.Fragment>
<Typography variant="body2" color="textSecondary" mt={2}>
Burnt tokens
</Typography>
<Stack sx={{ mb: 2, mt: 1 }} gap={0.5}>
{issuedAndBurnt.burnt.map((item) => (
<IssuedBurntTokenAmount
key={item.tokenId}
tokenId={item.tokenId}
amount={item.amount}
networkType={wallet.networkType}
color={'error'}
/>
))}
</Stack>
</React.Fragment>
) : null}
{issuedAndBurnt.issued.length > 0 ? (
<React.Fragment>
<Typography variant="body2" color="textSecondary" mt={2}>
Issued tokens
</Typography>
<Stack sx={{ mb: 2, mt: 1 }} gap={0.5}>
{issuedAndBurnt.issued.map((item) => (
<IssuedBurntTokenAmount
key={item.tokenId}
tokenId={item.tokenId}
amount={item.amount}
networkType={wallet.networkType}
color={'success'}
/>
))}
</Stack>
</React.Fragment>
) : null}
</React.Fragment>
);
};

export default TxDisplay;
4 changes: 2 additions & 2 deletions apps/wallet/src/hooks/useIssuedAndBurntTokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ const extractTokens = (
};

const useIssuedAndBurntTokens = (
tx: wasm.UnsignedTransaction | wasm.Transaction,
tx: wasm.UnsignedTransaction | wasm.Transaction | undefined,
boxes: Array<wasm.ErgoBox>,
) => {
const [issued, setIssued] = useState<Array<TokenType>>([]);
const [burnt, setBurnt] = useState<Array<TokenType>>([]);
const [storedTxId, setStoredTxId] = useState('');
const [loading, setLoading] = useState(false);
useEffect(() => {
if (!loading && storedTxId !== tx.id().to_str()) {
if (tx && !loading && storedTxId !== tx.id().to_str()) {
setLoading(true);
const inputs = tx.inputs();
const tokens = new Map<string, bigint>();
Expand Down
4 changes: 2 additions & 2 deletions apps/wallet/src/hooks/useTxValues.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ interface Values {
}

const useTxValues = (
tx: wasm.Transaction | wasm.UnsignedTransaction,
tx: wasm.Transaction | wasm.UnsignedTransaction | undefined,
boxes: Array<wasm.ErgoBox>,
wallet: StateWallet,
) => {
Expand All @@ -25,7 +25,7 @@ const useTxValues = (
});
useEffect(() => {
const unsigned = tx;
if (txValues.txId !== unsigned.id().to_str()) {
if (unsigned && txValues.txId !== unsigned.id().to_str()) {
const values = extractErgAndTokenSpent(wallet, boxes, unsigned);
const incoming =
values.value < 0n ||
Expand Down
31 changes: 4 additions & 27 deletions apps/wallet/src/pages/wallet-page/send/sign-tx/TxSignValues.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { openTxInBrowser } from '@/action/tx';
import useTxValues from '@/hooks/useTxValues';
import { Box, FormHelperText, IconButton, Typography } from '@mui/material';
import { OpenInNew } from '@mui/icons-material';
import { Box, FormHelperText, Typography } from '@mui/material';
import { ErgoBox } from 'ergo-lib-wasm-browser';
import * as wasm from 'ergo-lib-wasm-browser';
import React from 'react';
Expand All @@ -14,7 +12,6 @@ interface WalletSignNormalPropsType {
tx: wasm.UnsignedTransaction | wasm.Transaction;
boxes: Array<ErgoBox>;
wallet: StateWallet;
date?: string;
}

const TxSignValues = (props: WalletSignNormalPropsType) => {
Expand All @@ -24,8 +21,6 @@ const TxSignValues = (props: WalletSignNormalPropsType) => {
props.boxes,
props.wallet,
);
const openTx = () =>
openTxInBrowser(props.wallet.networkType, props.tx.id().to_str());
return (
<Box>
{valuesDirection.outgoing ? (
Expand Down Expand Up @@ -76,27 +71,9 @@ const TxSignValues = (props: WalletSignNormalPropsType) => {
)}
</React.Fragment>
) : null}
{props.date ? (
<React.Fragment>
<Typography variant="body2" color="textSecondary" mt={2}>
Received on
</Typography>
<Typography mb={2}>{props.date}</Typography>
<Typography variant="body2" color="textSecondary">
Transaction Id
</Typography>
<Typography mb={2} sx={{ overflowWrap: 'anywhere' }} onClick={openTx}>
{props.tx.id().to_str()}
<IconButton>
<OpenInNew />
</IconButton>
</Typography>
</React.Fragment>
) : (
<FormHelperText sx={{ mb: 2 }}>
These amount will be spent when transaction proceed.
</FormHelperText>
)}
<FormHelperText sx={{ mb: 2 }}>
These amount will be spent when transaction proceed.
</FormHelperText>
<UnBalancedTokensAmount
amounts={issuedAndBurnt.burnt}
color="error"
Expand Down
44 changes: 44 additions & 0 deletions apps/wallet/src/pages/wallet-page/transaction/TxAssetDetail.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import TokenAmountDisplay from '@/components/amounts-display/TokenAmountDisplay';
import DisplayId from '@/components/display-id/DisplayId';
import useAssetDetail from '@/hooks/useAssetDetail';
import { getValueColor } from '@/utils/functions';
import { Avatar, Box, Typography } from '@mui/material';
import React from 'react';

interface TxAssetDetailPropsType {
id: string;
amount: bigint;
networkType: string;
}
const TxAssetDetail = (props: TxAssetDetailPropsType) => {
const details = useAssetDetail(props.id, props.networkType);
if (props.amount === 0n) return null;
const color = getValueColor(props.amount);
return (
<React.Fragment>
<Box sx={{ float: 'left', mr: 2 }}>
{details.logo ? (
<Avatar alt={details.name}>
<details.logo />
</Avatar>
) : (
<Avatar alt={details.name} src="/" />
)}
</Box>
<Box display="flex">
<Typography sx={{ flexGrow: 1 }}>{details.name}</Typography>
<Typography color={color}>
{props.amount > 0 ? '+' : ''}
<TokenAmountDisplay amount={props.amount} decimal={details.decimal} />
</Typography>
</Box>
<DisplayId
variant="body2"
color={color}
id={props.amount > 0 ? 'Received' : 'Sent'}
/>
</React.Fragment>
);
};

export default TxAssetDetail;
Original file line number Diff line number Diff line change
@@ -1,56 +1,68 @@
import BackButtonRouter from '@/components/back-button/BackButtonRouter';
import TransactionBoxes from '@/components/sign/transaction-boxes/TransactionBoxes';
import StateMessage from '@/components/state-message/StateMessage';
import TxDisplay from '@/components/tx/TxDisplay';
import useTransactionData from '@/hooks/useTransactionData';
import SvgIcon from '@/icons/SvgIcon';
import AppFrame from '@/layouts/AppFrame';
import TxSignValues from '@/pages/wallet-page/send/sign-tx/TxSignValues';
import { StateWallet } from '@/store/reducer/wallet';
import { IconButton } from '@mui/material';
import { CircularProgress, IconButton } from '@mui/material';
import InventoryIcon from '@mui/icons-material/Inventory2Outlined';
import React, { useState } from 'react';
import { useParams } from 'react-router-dom';

interface TransactionDetailsPropsType {
// txId: string;
wallet: StateWallet;
}

const WalletTransactionDetails = (props: TransactionDetailsPropsType) => {
const { txId } = useParams<{ txId: string }>();
const txData = useTransactionData(txId ?? '', props.wallet);
const { tx, boxes, date, loading } = useTransactionData(
txId ?? '',
props.wallet,
);
const [displayBoxes, setDisplayBoxes] = useState(false);
return (
<AppFrame
title="Transaction"
navigation={<BackButtonRouter />}
actions={
<IconButton>
<InventoryIcon onClick={() => setDisplayBoxes(!displayBoxes)} />
</IconButton>
tx ? (
<IconButton onClick={() => setDisplayBoxes(!displayBoxes)}>
<InventoryIcon />
</IconButton>
) : undefined
}
>
{txData.tx ? (
{loading ? (
<StateMessage
title="Loading Transaction"
description="Please wait"
icon={<CircularProgress />}
color={`primary.dark`}
disableIconShadow={true}
/>
) : tx ? (
<React.Fragment>
<TxSignValues
tx={txData.tx}
boxes={txData.boxes}
wallet={props.wallet}
date={txData.date}
/>
<TxDisplay wallet={props.wallet} boxes={boxes} tx={tx} date={date} />
<TransactionBoxes
open={displayBoxes}
handleClose={() => setDisplayBoxes(false)}
boxes={txData.boxes}
boxes={boxes}
wallet={props.wallet}
signed={txData.tx}
signed={tx}
/>
</React.Fragment>
) : undefined}
{/*<Typography fontSize="2rem" textAlign="center" color={color} mb={2}>*/}
{/* {transaction.amount}*/}
{/* <Typography component="span" ml={1}>*/}
{/* ERG*/}
{/* </Typography>*/}
{/*</Typography>*/}
) : (
<StateMessage
title="Transaction Not Found"
description="Transaction Not Found!!"
icon={
<SvgIcon icon="error" color="error" style={{ marginBottom: -8 }} />
}
color={`error.dark`}
/>
)}
</AppFrame>
);
};
Expand Down
Loading

0 comments on commit ffbedf9

Please sign in to comment.