Skip to content

Commit

Permalink
display transaction detail page
Browse files Browse the repository at this point in the history
  • Loading branch information
vorujack committed Sep 4, 2024
1 parent ed466ae commit c646e4f
Show file tree
Hide file tree
Showing 15 changed files with 302 additions and 82 deletions.
15 changes: 15 additions & 0 deletions apps/wallet/src/action/transaction.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { createEmptyArrayWithIndex } from '@/utils/functions';
import { deserialize } from './box';
import { AddressDbAction, BoxDbAction } from './db';

Expand All @@ -6,6 +7,7 @@ interface WalletTransactionType {
date: Date;
ergIn: bigint;
ergOut: bigint;
tokens: Map<string, bigint>;
}

const getWalletTransactionsTotal = async (
Expand All @@ -31,6 +33,7 @@ const getWalletTransactions = async (
date: new Date(),
ergIn: 0n,
ergOut: 0n,
tokens: new Map<string, bigint>(),
txId: item.txId,
}));
for (const txRaw of result) {
Expand All @@ -40,6 +43,18 @@ const getWalletTransactions = async (
);
for (const box of boxes) {
const boxWasm = deserialize(box.serialized);
const tokens = boxWasm.tokens();
const sign = boxWasm.tx_id().to_str() === txRaw.txId ? 1n : -1n;
createEmptyArrayWithIndex(tokens.len()).forEach((index) => {
const token = tokens.get(index);
const total =
(txRaw.tokens.get(token.id().to_str()) ?? 0n) +
sign * BigInt(token.amount().as_i64().to_str());
txRaw.tokens.set(token.id().to_str(), total);
if (total === 0n) {
txRaw.tokens.delete(token.id().to_str());
}
});
if (boxWasm.tx_id().to_str() === txRaw.txId) {
txRaw.ergIn += BigInt(boxWasm.value().as_i64().to_str());
txRaw.date = new Date(box.create_timestamp);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Box } from '@mui/material';
import { ReceiverTokenType } from '../../../types/sign-modal';
import { ReceiverTokenType } from '@/types/sign-modal';
import DisplayId from '../../display-id/DisplayId';
import TokenAmount from '../../token-amount/TokenAmount';
import { StateWallet } from '@/store/reducer/wallet';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const TransactionBoxes = (props: TransactionBoxesPropsType) => {
props.boxes ?? context.boxes,
props.signed ?? context.tx,
);
const networkType = context.networkType ? context.networkType : props.wallet?.networkType ?? '';
return (
<Drawer
anchor="bottom"
Expand Down Expand Up @@ -50,7 +51,7 @@ const TransactionBoxes = (props: TransactionBoxesPropsType) => {
{inputBoxes.map((item, index) => (
<BoxItem
tokens={item.tokens}
networkType={context.networkType}
networkType={networkType}
address={item.address}
amount={item.amount}
key={index}
Expand All @@ -69,7 +70,7 @@ const TransactionBoxes = (props: TransactionBoxesPropsType) => {
{outputBoxes.map((item, index) => (
<BoxItem
tokens={item.tokens}
networkType={context.networkType}
networkType={networkType}
address={item.address}
amount={item.amount}
key={index}
Expand Down
48 changes: 48 additions & 0 deletions apps/wallet/src/hooks/useTransactionData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { StateWallet } from '@/store/reducer/wallet';
import getChain from '@/utils/networks';
import { useEffect, useState } from 'react';
import * as wasm from 'ergo-lib-wasm-browser';


const useTransactionData = (
txId: string,
wallet: StateWallet
) => {
const [loadedTx, setLoadedTx] = useState<string>('');
const [loadedWalletId, setLoadedWalletId] = useState<string>('');
const [loading, setLoading] = useState<boolean>(false);
const [tx, setTx] = useState<wasm.Transaction>();
const [date, setDate] = useState('');
const [boxes, setBoxes] = useState<Array<wasm.ErgoBox>>([]);

useEffect(() => {
if(!loading){
const processingTxId = txId;
if(loadedWalletId !== `${wallet.id}` || txId !== loadedTx) {
console.log(loadedWalletId, loadedTx, txId);
setLoading(true);
const chain = getChain(wallet.networkType);
chain.getNetwork().getTransaction(processingTxId).then(tx => {
setLoadedTx(processingTxId);
setLoadedWalletId(`${wallet.id}`);
setTx(tx.tx);
setDate(tx.date);
setBoxes(tx.boxes);
setLoading(false)
}).catch((e) => {
console.log(e);
setTimeout(() => setLoading(false), 1000)
// setLoading(false)
});
}
}
}, [loadedTx, loadedWalletId, loading, txId, wallet.id, wallet.networkType]);
return {
tx,
boxes,
date,
loading
}
}

export default useTransactionData;
50 changes: 50 additions & 0 deletions apps/wallet/src/hooks/useTxValues.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { extractErgAndTokenSpent } from '@/action/tx';
import { StateWallet } from '@/store/reducer/wallet';
import { useEffect, useState } from 'react';
import * as wasm from 'ergo-lib-wasm-browser';

interface Values {
total: bigint;
txId: string;
tokens: { [tokenId: string]: bigint };
}

const useTxValues = (tx: wasm.Transaction | wasm.UnsignedTransaction, boxes: Array<wasm.ErgoBox>, wallet: StateWallet) => {
const [txValues, setTxValues] = useState<Values>({
total: 0n,
txId: '',
tokens: {}
});
const [valuesDirection, setValuesDirection] = useState({
incoming: false,
outgoing: false
});
useEffect(() => {
const unsigned = tx;
if (txValues.txId !== unsigned.id().to_str()) {
const values = extractErgAndTokenSpent(
wallet,
boxes,
unsigned
);
const incoming =
values.value < 0n ||
Object.values(values.tokens).filter((amount) => amount < 0n).length > 0;
const outgoing =
values.value > 0n ||
Object.values(values.tokens).filter((amount) => amount > 0n).length > 0;
setValuesDirection({ incoming, outgoing });
setTxValues({
total: values.value,
tokens: values.tokens,
txId: unsigned.id().to_str()
});
}
}, [txValues.txId, tx, wallet, boxes]);
return {
txValues,
valuesDirection
};
};

export default useTxValues;
5 changes: 5 additions & 0 deletions apps/wallet/src/pages/wallet-page/WalletPage.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import WalletTransactionDetails from '@/pages/wallet-page/transaction/WalletTransactionDetail';
import { useEffect, useState } from 'react';
import { GlobalStateType } from '@/store';
import { useSelector } from 'react-redux';
Expand Down Expand Up @@ -59,6 +60,10 @@ const WalletPage = () => {
path={WalletPageSuffix.WalletTransaction}
element={<WalletTransaction wallet={wallet} />}
/>
<Route
path={WalletPageSuffix.WalletTransactionDetail}
element={<WalletTransactionDetails wallet={wallet} />}
/>
<Route
path={WalletPageSuffix.WalletAddress}
element={<WalletAddress wallet={wallet} />}
Expand Down
6 changes: 3 additions & 3 deletions apps/wallet/src/pages/wallet-page/home/RecentTransactions.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import useWalletTransaction from '@/hooks/useWalletTransaction';
import { Box, Divider, Stack } from '@mui/material';
import { Box, Stack } from '@mui/material';
import StateMessage from '@/components/state-message/StateMessage';
import SvgIcon from '@/icons/SvgIcon';
import TransactionItem from '../transaction/TransactionItem';
Expand All @@ -25,12 +25,12 @@ const RecentTransactions = (props: RecentTransactionsPropsType) => {
disabled={transactions.length === 0}
/>
{transactions.length > 0 ? (
<Stack divider={<Divider />} spacing={1}>
<Stack spacing={1}>
{transactions.map((item, index) => (
<TransactionItem
tx={item}
key={index}
network_type={props.wallet.networkType}
wallet={props.wallet}
/>
))}
</Stack>
Expand Down
76 changes: 31 additions & 45 deletions apps/wallet/src/pages/wallet-page/send/sign-tx/TxSignValues.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { Box, FormHelperText, Typography } from '@mui/material';
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 { ErgoBox } from 'ergo-lib-wasm-browser';
import * as wasm from 'ergo-lib-wasm-browser';
import React, { useEffect, useState } from 'react';
import { extractErgAndTokenSpent } from '@/action/tx';
import React from 'react';
import TokenAmount from '@/components/token-amount/TokenAmount';
import { StateWallet } from '@/store/reducer/wallet';
import useIssuedAndBurntTokens from '@/hooks/useIssuedAndBurntTokens';
Expand All @@ -12,47 +14,13 @@ interface WalletSignNormalPropsType {
tx: wasm.UnsignedTransaction | wasm.Transaction;
boxes: Array<ErgoBox>;
wallet: StateWallet;
}

interface Values {
total: bigint;
txId: string;
tokens: { [tokenId: string]: bigint };
date?: string;
}

const TxSignValues = (props: WalletSignNormalPropsType) => {
const [txValues, setTxValues] = useState<Values>({
total: 0n,
txId: '',
tokens: {},
});
const issuedAndBurnt = useIssuedAndBurntTokens(props.tx, props.boxes);
const [valuesDirection, setValuesDirection] = useState({
incoming: false,
outgoing: false,
});
useEffect(() => {
const unsigned = props.tx;
if (txValues.txId !== unsigned.id().to_str()) {
const values = extractErgAndTokenSpent(
props.wallet,
props.boxes,
unsigned,
);
const incoming =
values.value < 0n ||
Object.values(values.tokens).filter((amount) => amount < 0n).length > 0;
const outgoing =
values.value > 0n ||
Object.values(values.tokens).filter((amount) => amount > 0n).length > 0;
setValuesDirection({ incoming, outgoing });
setTxValues({
total: values.value,
tokens: values.tokens,
txId: unsigned.id().to_str(),
});
}
}, [txValues.txId, props.tx, props.wallet, props.boxes]);
const {txValues, valuesDirection} = useTxValues(props.tx, props.boxes, props.wallet)
const openTx = () => openTxInBrowser(props.wallet.networkType, props.tx.id().to_str());
return (
<Box>
{valuesDirection.outgoing ? (
Expand All @@ -75,7 +43,7 @@ const TxSignValues = (props: WalletSignNormalPropsType) => {
networkType={props.wallet.networkType}
key={tokenId}
/>
) : null,
) : null
)}
</React.Fragment>
) : null}
Expand All @@ -99,13 +67,31 @@ const TxSignValues = (props: WalletSignNormalPropsType) => {
networkType={props.wallet.networkType}
key={tokenId}
/>
) : null,
) : null
)}
</React.Fragment>
) : null}
<FormHelperText sx={{ mb: 2 }}>
These amount will be spent when transaction proceed.
</FormHelperText>
{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>
)}
<UnBalancedTokensAmount
amounts={issuedAndBurnt.burnt}
color="error"
Expand Down
Loading

0 comments on commit c646e4f

Please sign in to comment.