@@ -5,6 +5,7 @@ import { useSearchParams } from "next/navigation";
55import TransactionDetailsModal from "../components/TransactionDetailsModal" ;
66import {
77 asArray ,
8+ CopyButton ,
89 EmptyState ,
910 formatBalance ,
1011 PageHeader ,
@@ -18,6 +19,18 @@ import { getAccount, getAllBalances, getAllTransactions, getOwnedNfts, getOwnedO
1819
1920type AccountTab = "coins" | "nfts" | "objects" | "activity" ;
2021
22+ function readBytes ( value : unknown , key : string ) {
23+ const record = typeof value === "object" && value !== null && ! Array . isArray ( value ) ? ( value as Record < string , unknown > ) : { } ;
24+ const item = record [ key ] ;
25+ if ( ! Array . isArray ( item ) ) return [ ] ;
26+ return item . filter ( ( entry ) : entry is number => typeof entry === "number" && Number . isFinite ( entry ) ) ;
27+ }
28+
29+ function formatHex ( bytes : number [ ] ) {
30+ if ( bytes . length === 0 ) return "-" ;
31+ return `0x${ bytes . map ( ( byte ) => Math . max ( 0 , Math . min ( 255 , byte ) ) . toString ( 16 ) . padStart ( 2 , "0" ) ) . join ( "" ) } ` ;
32+ }
33+
2134function AccountContent ( ) {
2235 const searchParams = useSearchParams ( ) ;
2336 const [ address , setAddress ] = useState ( searchParams . get ( "address" ) ?? "" ) ;
@@ -91,11 +104,16 @@ function AccountContent() {
91104 </ PageHeader >
92105
93106 { account ? (
94- < section className = "panel" style = { { marginTop : 18 } } >
107+ < section className = "panel account-state-panel" >
95108 < div className = "panel-head" >
96109 < div >
97110 < h2 className = "panel-title" > Account State</ h2 >
98- < p className = "panel-subtitle mono" > { readString ( account , "address" , address ) } </ p >
111+ < div className = "panel-subtitle mono account-address-copy" >
112+ < span className = "copy-row copy-row--wrap" >
113+ < span className = "break-anywhere" > { readString ( account , "address" , address ) } </ span >
114+ < CopyButton value = { readString ( account , "address" , address ) } label = "Copy account address" />
115+ </ span >
116+ </ div >
99117 </ div >
100118 < StatusPill label = { `Sequence ${ readString ( account , "sequence_number" , "0" ) } ` } />
101119 </ div >
@@ -174,17 +192,20 @@ function AccountContent() {
174192 < div className = "data-row" key = { `${ hash } -${ index } ` } >
175193 < div >
176194 < p className = "tiny-label" > Txn Hash</ p >
177- < button className = "hash-button mono" type = "button" onClick = { ( ) => openTransaction ( hash ) } >
178- { shortHash ( hash ) }
179- </ button >
195+ < span className = "copy-row copy-row--wrap" >
196+ < button className = "hash-button mono break-anywhere" type = "button" onClick = { ( ) => openTransaction ( hash ) } >
197+ { hash }
198+ </ button >
199+ < CopyButton value = { hash } label = "Copy transaction hash" />
200+ </ span >
180201 </ div >
181202 < div >
182203 < p className = "tiny-label" > Type</ p >
183204 < span className = "tag" > { readString ( transaction , "tx_type" , "operation" ) } </ span >
184205 </ div >
185206 < div >
186207 < p className = "tiny-label" > Target</ p >
187- < span className = "mono muted-text" > { readString ( transaction , "module" , "-" ) } </ span >
208+ < span className = "mono muted-text" > { shortHash ( readString ( transaction , "module" , "-" ) ) } </ span >
188209 </ div >
189210 < div >
190211 < p className = "tiny-label" > Status</ p >
@@ -206,24 +227,53 @@ function AccountContent() {
206227 < div className = "data-list" >
207228 { objects . map ( ( object , index ) => {
208229 const objectId = readString ( object , "object_id" , readString ( object , "id" , `object-${ index } ` ) ) ;
230+ const objectType = readString ( object , "type_" , readString ( object , "type" , readString ( object , "object_type" , "-" ) ) ) ;
231+ const owner = readString ( object , "owner" , address ) ;
232+ const dataBytes = readBytes ( object , "data" ) ;
233+ const objectJson =
234+ object && typeof object === "object" && ! Array . isArray ( object )
235+ ? { ...( object as Record < string , unknown > ) , data_hex : formatHex ( dataBytes ) }
236+ : { value : object , data_hex : formatHex ( dataBytes ) } ;
209237 return (
210- < div className = "data-row" key = { `${ objectId } -${ index } ` } >
211- < div className = "primary-text" >
212- < strong className = "mono" > { shortHash ( objectId ) } </ strong >
213- < div className = "muted-text mono" > { readString ( object , "type" , readString ( object , "object_type" , "object" ) ) } </ div >
214- </ div >
215- < div >
216- < p className = "tiny-label" > Owner</ p >
217- < span className = "mono muted-text" > { shortHash ( readString ( object , "owner" , address ) ) } </ span >
238+ < div className = "data-row data-row--objects" key = { `${ objectId } -${ index } ` } >
239+ < div className = "object-main primary-text" >
240+ < p className = "tiny-label" > Object ID</ p >
241+ < span className = "copy-row copy-row--inline" >
242+ < strong className = "mono break-anywhere" > { objectId } </ strong >
243+ < CopyButton value = { objectId } label = "Copy object id" />
244+ </ span >
218245 </ div >
219- < div >
220- < p className = "tiny-label" > Version</ p >
221- < span className = "mono" > { readString ( object , "version" , "-" ) } </ span >
222- </ div >
223- < div >
224- < p className = "tiny-label" > Status</ p >
225- < StatusPill label = { readString ( object , "status" , "owned" ) } />
246+
247+ < div className = "object-detail-grid" >
248+ < div className = "object-detail-field object-detail-field--wide" >
249+ < p className = "tiny-label" > Type</ p >
250+ < span className = "mono muted-text break-anywhere" > { objectType } </ span >
251+ </ div >
252+ < div className = "object-detail-field object-detail-field--wide" >
253+ < p className = "tiny-label" > Owner</ p >
254+ < span className = "copy-row copy-row--inline" >
255+ < span className = "mono muted-text break-anywhere" > { owner } </ span >
256+ < CopyButton value = { owner } label = "Copy owner address" />
257+ </ span >
258+ </ div >
259+ < div className = "object-detail-field" >
260+ < p className = "tiny-label" > Version</ p >
261+ < span className = "mono" > { readString ( object , "version" , "-" ) } </ span >
262+ </ div >
263+ < div className = "object-detail-field" >
264+ < p className = "tiny-label" > Data Bytes</ p >
265+ < span className = "mono" > { dataBytes . length . toLocaleString ( ) } </ span >
266+ </ div >
267+ < div className = "object-detail-field" >
268+ < p className = "tiny-label" > Status</ p >
269+ < StatusPill label = { readString ( object , "status" , "owned" ) } />
270+ </ div >
226271 </ div >
272+
273+ < details className = "object-json-details" >
274+ < summary > Object JSON</ summary >
275+ < pre className = "custom-scrollbar" > { JSON . stringify ( objectJson , null , 2 ) } </ pre >
276+ </ details >
227277 </ div >
228278 ) ;
229279 } ) }
0 commit comments