1
1
import { CopyToClipboardControl , Tooltip } from "@namada/components" ;
2
- import { TransactionHistory as TransactionHistoryType } from "@namada/indexer-client" ;
3
2
import { shortenAddress } from "@namada/utils" ;
4
3
import { TokenCurrency } from "App/Common/TokenCurrency" ;
5
4
import { AssetImage } from "App/Transfer/AssetImage" ;
6
- import { isShieldedAddress , isTransparentAddress } from "App/Transfer/common" ;
7
- import { indexerApiAtom } from "atoms/api" ;
8
- import { fetchBlockTimestampByHeight } from "atoms/balance/services" ;
5
+ import {
6
+ isMaspAddress ,
7
+ isShieldedAddress ,
8
+ isTransparentAddress ,
9
+ } from "App/Transfer/common" ;
9
10
import { chainAssetsMapAtom , nativeTokenAddressAtom } from "atoms/chain" ;
11
+ import { TransactionHistory as TransactionHistoryType } from "atoms/transactions/atoms" ;
10
12
import { allValidatorsAtom } from "atoms/validators" ;
11
13
import BigNumber from "bignumber.js" ;
12
14
import clsx from "clsx" ;
13
15
import { useAtomValue } from "jotai" ;
14
- import { useEffect , useState } from "react" ;
15
16
import { FaLock } from "react-icons/fa6" ;
16
17
import {
17
18
IoCheckmarkCircleOutline ,
@@ -61,19 +62,6 @@ export function getToken(
61
62
return undefined ;
62
63
}
63
64
64
- const getTitle = ( kind : string | undefined , isReceived : boolean ) : string => {
65
- if ( ! kind ) return "Unknown" ;
66
- if ( isReceived ) return "Receive" ;
67
- if ( kind . startsWith ( "ibc" ) ) return "IBC Transfer" ;
68
- if ( kind === "bond" ) return "Stake" ;
69
- if ( kind === "claimRewards" ) return "Claim Rewards" ;
70
- if ( kind === "transparentTransfer" ) return "Transparent Transfer" ;
71
- if ( kind === "shieldingTransfer" ) return "Shielding Transfer" ;
72
- if ( kind === "unshieldingTransfer" ) return "Unshielding Transfer" ;
73
- if ( kind === "shieldedTransfer" ) return "Shielded Transfer" ;
74
- return "Transfer" ;
75
- } ;
76
-
77
65
const getBondTransactionInfo = (
78
66
tx : Tx [ "tx" ]
79
67
) : { amount : BigNumber ; sender ?: string ; receiver ?: string } | undefined => {
@@ -126,7 +114,6 @@ export const TransactionCard = ({
126
114
tx : transactionTopLevel ,
127
115
} : Props ) : JSX . Element => {
128
116
const transaction = transactionTopLevel . tx ;
129
- const isReceived = transactionTopLevel ?. kind === "received" ;
130
117
const nativeToken = useAtomValue ( nativeTokenAddressAtom ) . data ;
131
118
const token = getToken ( transaction , nativeToken ?? "" ) ;
132
119
const chainAssetsMap = useAtomValue ( chainAssetsMapAtom ) ;
@@ -142,47 +129,43 @@ export const TransactionCard = ({
142
129
: undefined ;
143
130
const receiver = txnInfo ?. receiver ;
144
131
const sender = txnInfo ?. sender ;
132
+ const isReceived = transactionTopLevel ?. kind === "received" ;
133
+ const isInternalUnshield =
134
+ transactionTopLevel ?. kind === "received" && isMaspAddress ( sender ?? "" ) ;
145
135
const transactionFailed = transaction ?. exitCode === "rejected" ;
146
136
const validators = useAtomValue ( allValidatorsAtom ) ;
147
137
const validator = validators ?. data ?. find ( ( v ) => v . address === receiver ) ;
148
- const api = useAtomValue ( indexerApiAtom ) ;
149
- const [ timestamp , setTimestamp ] = useState < number | undefined > ( undefined ) ;
150
-
151
- useEffect ( ( ) => {
152
- const getBlockTimestamp = async ( ) : Promise < void > => {
153
- // TODO: need to update the type on indexer
154
- // @ts -expect-error need to update the type on indexer
155
- if ( transactionTopLevel ?. blockHeight && api ) {
156
- try {
157
- const timestamp = await fetchBlockTimestampByHeight (
158
- api ,
159
- // @ts -expect-error need to update the type on indexer
160
- transactionTopLevel . blockHeight
161
- ) ;
162
- setTimestamp ( timestamp ) ;
163
- } catch ( error ) {
164
- console . error ( "Failed to fetch block height:" , error ) ;
165
- }
166
- }
167
- } ;
168
-
169
- getBlockTimestamp ( ) ;
170
- // @ts -expect-error need to update the type on indexer
171
- } , [ api , transactionTopLevel ?. blockHeight ] ) ;
172
138
173
139
const renderKeplrIcon = ( address : string ) : JSX . Element | null => {
174
140
if ( isShieldedAddress ( address ) ) return null ;
175
141
if ( isTransparentAddress ( address ) ) return null ;
176
142
return < img src = { keplrSvg } height = { 18 } width = { 18 } /> ;
177
143
} ;
178
144
145
+ const getTitle = ( tx : Tx [ "tx" ] ) : string => {
146
+ const kind = tx ?. kind ;
147
+
148
+ if ( ! kind ) return "Unknown" ;
149
+ if ( isInternalUnshield ) return "Unshielding Transfer" ;
150
+ if ( isReceived ) return "Receive" ;
151
+ if ( kind . startsWith ( "ibc" ) ) return "IBC Transfer" ;
152
+ if ( kind === "bond" ) return "Stake" ;
153
+ if ( kind === "claimRewards" ) return "Claim Rewards" ;
154
+ if ( kind === "transparentTransfer" ) return "Transparent Transfer" ;
155
+ if ( kind === "shieldingTransfer" ) return "Shielding Transfer" ;
156
+ if ( kind === "unshieldingTransfer" ) return "Unshielding Transfer" ;
157
+ if ( kind === "shieldedTransfer" ) return "Shielded Transfer" ;
158
+ return "Transfer" ;
159
+ } ;
160
+
179
161
return (
180
162
< article
181
163
className = { twMerge (
182
164
clsx (
183
165
"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 items-center my-1 font-semibold" ,
184
- "gap-5 bg-neutral-800 rounded-sm px-5 py-5 text-white border border-transparent" ,
185
- "transition-colors duration-200 hover:border-neutral-500"
166
+ "gap-5 bg-neutral-800 rounded-sm px-5 text-white border border-transparent" ,
167
+ "transition-colors duration-200 hover:border-neutral-500" ,
168
+ isBondingTransaction && validator ?. imageUrl ? "py-3" : "py-5"
186
169
)
187
170
) }
188
171
>
@@ -212,20 +195,20 @@ export const TransactionCard = ({
212
195
} )
213
196
) }
214
197
>
215
- { getTitle ( transaction ?. kind , isReceived ) } { " " }
198
+ { transactionFailed && "Failed" } { getTitle ( transaction ) } { " " }
216
199
< div className = "relative group/tooltip" >
217
200
< CopyToClipboardControl
218
201
className = "ml-1.5 text-neutral-400"
219
202
value = { transaction ?. txId ?? "" }
220
203
/>
221
- < Tooltip position = "right" className = "p-2 -mr-3 w-[150px]" >
204
+ < Tooltip position = "right" className = "p-2 -mr-3 w-[150px] z-10 " >
222
205
Copy transaction hash
223
206
</ Tooltip >
224
207
</ div >
225
208
</ h3 >
226
209
< h3 className = "text-neutral-400" >
227
- { timestamp ?
228
- new Date ( timestamp * 1000 )
210
+ { transactionTopLevel ?. timestamp ?
211
+ new Date ( transactionTopLevel . timestamp * 1000 )
229
212
. toLocaleString ( "en-US" , {
230
213
day : "2-digit" ,
231
214
month : "2-digit" ,
0 commit comments