Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
frontend
Commits
341acb38
Commit
341acb38
authored
Feb 17, 2025
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
user ops
parent
d13f87b4
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
215 additions
and
233 deletions
+215
-233
[hash].tsx
pages/op/[hash].tsx
+2
-2
ops.tsx
pages/ops.tsx
+2
-2
switch.tsx
toolkit/chakra/switch.tsx
+3
-2
UserOp.tsx
ui/pages/UserOp.tsx
+8
-8
ContainerWithScrollY.tsx
ui/shared/ContainerWithScrollY.tsx
+2
-2
DetailedInfo.tsx
ui/shared/DetailedInfo/DetailedInfo.tsx
+3
-3
UserOpEntity.tsx
ui/shared/entities/userOp/UserOpEntity.tsx
+2
-3
TxInterpretation.tsx
ui/shared/tx/interpretation/TxInterpretation.tsx
+1
-1
UserOpSponsorType.tsx
ui/shared/userOps/UserOpSponsorType.tsx
+3
-2
UserOpCallDataSwitch.tsx
ui/userOp/UserOpCallDataSwitch.tsx
+18
-7
UserOpDetails.tsx
ui/userOp/UserOpDetails.tsx
+167
-198
UserOpRaw.tsx
ui/userOp/UserOpRaw.tsx
+2
-2
UserOpSubHeading.tsx
ui/userOp/UserOpSubHeading.tsx
+2
-1
No files found.
pages/op/[hash].tsx
View file @
341acb38
...
@@ -5,12 +5,12 @@ import React from 'react';
...
@@ -5,12 +5,12 @@ import React from 'react';
import
type
{
Props
}
from
'
nextjs/getServerSideProps
'
;
import
type
{
Props
}
from
'
nextjs/getServerSideProps
'
;
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
//
const UserOp = dynamic(() => import('ui/pages/UserOp'), { ssr: false });
const
UserOp
=
dynamic
(()
=>
import
(
'
ui/pages/UserOp
'
),
{
ssr
:
false
});
const
Page
:
NextPage
<
Props
>
=
(
props
:
Props
)
=>
{
const
Page
:
NextPage
<
Props
>
=
(
props
:
Props
)
=>
{
return
(
return
(
<
PageNextJs
pathname=
"/op/[hash]"
query=
{
props
.
query
}
>
<
PageNextJs
pathname=
"/op/[hash]"
query=
{
props
.
query
}
>
{
/* <UserOp/> */
}
<
UserOp
/>
</
PageNextJs
>
</
PageNextJs
>
);
);
};
};
...
...
pages/ops.tsx
View file @
341acb38
...
@@ -4,12 +4,12 @@ import React from 'react';
...
@@ -4,12 +4,12 @@ import React from 'react';
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
//
const UserOps = dynamic(() => import('ui/pages/UserOps'), { ssr: false });
const
UserOps
=
dynamic
(()
=>
import
(
'
ui/pages/UserOps
'
),
{
ssr
:
false
});
const
Page
:
NextPage
=
()
=>
{
const
Page
:
NextPage
=
()
=>
{
return
(
return
(
<
PageNextJs
pathname=
"/ops"
>
<
PageNextJs
pathname=
"/ops"
>
{
/* <UserOps/> */
}
<
UserOps
/>
</
PageNextJs
>
</
PageNextJs
>
);
);
};
};
...
...
toolkit/chakra/switch.tsx
View file @
341acb38
...
@@ -3,6 +3,7 @@ import * as React from 'react';
...
@@ -3,6 +3,7 @@ import * as React from 'react';
export
interface
SwitchProps
extends
ChakraSwitch
.
RootProps
{
export
interface
SwitchProps
extends
ChakraSwitch
.
RootProps
{
inputProps
?:
React
.
InputHTMLAttributes
<
HTMLInputElement
>
;
inputProps
?:
React
.
InputHTMLAttributes
<
HTMLInputElement
>
;
labelProps
?:
ChakraSwitch
.
LabelProps
;
rootRef
?:
React
.
Ref
<
HTMLLabelElement
>
;
rootRef
?:
React
.
Ref
<
HTMLLabelElement
>
;
trackLabel
?:
{
on
:
React
.
ReactNode
;
off
:
React
.
ReactNode
};
trackLabel
?:
{
on
:
React
.
ReactNode
;
off
:
React
.
ReactNode
};
thumbLabel
?:
{
on
:
React
.
ReactNode
;
off
:
React
.
ReactNode
};
thumbLabel
?:
{
on
:
React
.
ReactNode
;
off
:
React
.
ReactNode
};
...
@@ -10,7 +11,7 @@ export interface SwitchProps extends ChakraSwitch.RootProps {
...
@@ -10,7 +11,7 @@ export interface SwitchProps extends ChakraSwitch.RootProps {
export
const
Switch
=
React
.
forwardRef
<
HTMLInputElement
,
SwitchProps
>
(
export
const
Switch
=
React
.
forwardRef
<
HTMLInputElement
,
SwitchProps
>
(
function
Switch
(
props
,
ref
)
{
function
Switch
(
props
,
ref
)
{
const
{
inputProps
,
children
,
rootRef
,
trackLabel
,
thumbLabel
,
...
rest
}
=
const
{
inputProps
,
children
,
rootRef
,
trackLabel
,
thumbLabel
,
labelProps
,
...
rest
}
=
props
;
props
;
return
(
return
(
...
@@ -31,7 +32,7 @@ export const Switch = React.forwardRef<HTMLInputElement, SwitchProps>(
...
@@ -31,7 +32,7 @@ export const Switch = React.forwardRef<HTMLInputElement, SwitchProps>(
)
}
)
}
</
ChakraSwitch
.
Control
>
</
ChakraSwitch
.
Control
>
{
children
!=
null
&&
(
{
children
!=
null
&&
(
<
ChakraSwitch
.
Label
>
{
children
}
</
ChakraSwitch
.
Label
>
<
ChakraSwitch
.
Label
{
...
labelProps
}
>
{
children
}
</
ChakraSwitch
.
Label
>
)
}
)
}
</
ChakraSwitch
.
Root
>
</
ChakraSwitch
.
Root
>
);
);
...
...
ui/pages/UserOp.tsx
View file @
341acb38
...
@@ -2,9 +2,9 @@ import { inRange } from 'es-toolkit';
...
@@ -2,9 +2,9 @@ import { inRange } from 'es-toolkit';
import
{
useRouter
}
from
'
next/router
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
TabItemRegular
}
from
'
toolkit/components/AdaptiveTabs/types
'
;
import
type
{
Log
}
from
'
types/api/log
'
;
import
type
{
Log
}
from
'
types/api/log
'
;
import
type
{
TokenTransfer
}
from
'
types/api/tokenTransfer
'
;
import
type
{
TokenTransfer
}
from
'
types/api/tokenTransfer
'
;
import
type
{
RoutedTab
}
from
'
ui/shared/Tabs/types
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
{
useAppContext
}
from
'
lib/contexts/app
'
;
import
{
useAppContext
}
from
'
lib/contexts/app
'
;
...
@@ -12,11 +12,11 @@ import throwOnAbsentParamError from 'lib/errors/throwOnAbsentParamError';
...
@@ -12,11 +12,11 @@ import throwOnAbsentParamError from 'lib/errors/throwOnAbsentParamError';
import
throwOnResourceLoadError
from
'
lib/errors/throwOnResourceLoadError
'
;
import
throwOnResourceLoadError
from
'
lib/errors/throwOnResourceLoadError
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
{
USER_OP
}
from
'
stubs/userOps
'
;
import
{
USER_OP
}
from
'
stubs/userOps
'
;
import
RoutedTabs
from
'
toolkit/components/RoutedTabs/RoutedTabs
'
;
import
RoutedTabsSkeleton
from
'
toolkit/components/RoutedTabs/RoutedTabsSkeleton
'
;
import
useActiveTabFromQuery
from
'
toolkit/components/RoutedTabs/useActiveTabFromQuery
'
;
import
TextAd
from
'
ui/shared/ad/TextAd
'
;
import
TextAd
from
'
ui/shared/ad/TextAd
'
;
import
PageTitle
from
'
ui/shared/Page/PageTitle
'
;
import
PageTitle
from
'
ui/shared/Page/PageTitle
'
;
import
RoutedTabs
from
'
ui/shared/Tabs/RoutedTabs
'
;
import
TabsSkeleton
from
'
ui/shared/Tabs/TabsSkeleton
'
;
import
useTabIndexFromQuery
from
'
ui/shared/Tabs/useTabIndexFromQuery
'
;
import
TxLogs
from
'
ui/tx/TxLogs
'
;
import
TxLogs
from
'
ui/tx/TxLogs
'
;
import
TxTokenTransfer
from
'
ui/tx/TxTokenTransfer
'
;
import
TxTokenTransfer
from
'
ui/tx/TxTokenTransfer
'
;
import
useTxQuery
from
'
ui/tx/useTxQuery
'
;
import
useTxQuery
from
'
ui/tx/useTxQuery
'
;
...
@@ -65,7 +65,7 @@ const UserOp = () => {
...
@@ -65,7 +65,7 @@ const UserOp = () => {
}
}
},
[
userOpQuery
.
data
]);
},
[
userOpQuery
.
data
]);
const
tabs
:
Array
<
RoutedTab
>
=
React
.
useMemo
(()
=>
([
const
tabs
:
Array
<
TabItemRegular
>
=
React
.
useMemo
(()
=>
([
{
id
:
'
index
'
,
title
:
'
Details
'
,
component
:
<
UserOpDetails
query=
{
userOpQuery
}
/>
},
{
id
:
'
index
'
,
title
:
'
Details
'
,
component
:
<
UserOpDetails
query=
{
userOpQuery
}
/>
},
{
{
id
:
'
token_transfers
'
,
id
:
'
token_transfers
'
,
...
@@ -76,7 +76,7 @@ const UserOp = () => {
...
@@ -76,7 +76,7 @@ const UserOp = () => {
{
id
:
'
raw
'
,
title
:
'
Raw
'
,
component
:
<
UserOpRaw
rawData=
{
userOpQuery
.
data
?.
raw
}
isLoading=
{
userOpQuery
.
isPlaceholderData
}
/>
},
{
id
:
'
raw
'
,
title
:
'
Raw
'
,
component
:
<
UserOpRaw
rawData=
{
userOpQuery
.
data
?.
raw
}
isLoading=
{
userOpQuery
.
isPlaceholderData
}
/>
},
]),
[
userOpQuery
,
txQuery
,
filterTokenTransfersByLogIndex
,
filterLogsByLogIndex
]);
]),
[
userOpQuery
,
txQuery
,
filterTokenTransfersByLogIndex
,
filterLogsByLogIndex
]);
const
tabIndex
=
useTabIndex
FromQuery
(
tabs
);
const
activeTab
=
useActiveTab
FromQuery
(
tabs
);
const
backLink
=
React
.
useMemo
(()
=>
{
const
backLink
=
React
.
useMemo
(()
=>
{
const
hasGoBackLink
=
appProps
.
referrer
&&
appProps
.
referrer
.
includes
(
'
/ops
'
);
const
hasGoBackLink
=
appProps
.
referrer
&&
appProps
.
referrer
.
includes
(
'
/ops
'
);
...
@@ -106,8 +106,8 @@ const UserOp = () => {
...
@@ -106,8 +106,8 @@ const UserOp = () => {
/>
/>
{
userOpQuery
.
isPlaceholderData
?
(
{
userOpQuery
.
isPlaceholderData
?
(
<>
<>
<
TabsSkeleton
tabs=
{
tabs
}
mt=
{
6
}
/>
<
Routed
TabsSkeleton
tabs=
{
tabs
}
mt=
{
6
}
/>
{
tabs
[
tabIndex
]
?.
component
}
{
activeTab
?.
component
}
</>
</>
)
:
)
:
<
RoutedTabs
tabs=
{
tabs
}
/>
}
<
RoutedTabs
tabs=
{
tabs
}
/>
}
...
...
ui/shared/ContainerWithScrollY.tsx
View file @
341acb38
import
type
{
FlexProps
}
from
'
@chakra-ui/react
'
;
import
type
{
FlexProps
}
from
'
@chakra-ui/react
'
;
import
{
Flex
,
chakra
}
from
'
@chakra-ui/react
'
;
import
{
Flex
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
export
interface
Props
extends
FlexProps
{
export
interface
Props
extends
FlexProps
{
...
@@ -44,4 +44,4 @@ const ContainerWithScrollY = ({ gradientHeight, children, onScrollVisibilityChan
...
@@ -44,4 +44,4 @@ const ContainerWithScrollY = ({ gradientHeight, children, onScrollVisibilityChan
);
);
};
};
export
default
chakra
(
ContainerWithScrollY
)
;
export
default
ContainerWithScrollY
;
ui/shared/DetailedInfo/DetailedInfo.tsx
View file @
341acb38
...
@@ -73,11 +73,11 @@ export const ItemValue = ({ children, ...rest }: ItemValueProps) => {
...
@@ -73,11 +73,11 @@ export const ItemValue = ({ children, ...rest }: ItemValueProps) => {
);
);
};
};
export
const
ItemValueWithScroll
=
({
children
,
gradientHeight
,
onScrollVisibilityChange
,
className
}:
ContainerWithScrollY
.
Props
)
=>
{
export
const
ItemValueWithScroll
=
({
children
,
gradientHeight
,
onScrollVisibilityChange
,
...
rest
}:
ContainerWithScrollY
.
Props
)
=>
{
return
(
return
(
<
ItemValue
position=
"relative"
>
<
ItemValue
position=
"relative"
>
<
ContainerWithScrollY
.
default
<
ContainerWithScrollY
.
default
className=
{
className
}
{
...
rest
}
gradientHeight=
{
gradientHeight
}
gradientHeight=
{
gradientHeight
}
onScrollVisibilityChange=
{
onScrollVisibilityChange
}
onScrollVisibilityChange=
{
onScrollVisibilityChange
}
>
>
...
...
ui/shared/entities/userOp/UserOpEntity.tsx
View file @
341acb38
...
@@ -63,13 +63,12 @@ export interface EntityProps extends EntityBase.EntityBaseProps {
...
@@ -63,13 +63,12 @@ export interface EntityProps extends EntityBase.EntityBaseProps {
const
UserOpEntity
=
(
props
:
EntityProps
)
=>
{
const
UserOpEntity
=
(
props
:
EntityProps
)
=>
{
const
partsProps
=
distributeEntityProps
(
props
);
const
partsProps
=
distributeEntityProps
(
props
);
const
content
=
<
Content
{
...
partsProps
.
content
}
/>;
return
(
return
(
<
Container
{
...
partsProps
.
container
}
>
<
Container
{
...
partsProps
.
container
}
>
<
Icon
{
...
partsProps
.
icon
}
/>
<
Icon
{
...
partsProps
.
icon
}
/>
<
Link
{
...
partsProps
.
link
}
>
{
props
.
noLink
?
content
:
<
Link
{
...
partsProps
.
link
}
>
{
content
}
</
Link
>
}
<
Content
{
...
partsProps
.
content
}
/>
</
Link
>
<
Copy
{
...
partsProps
.
copy
}
/>
<
Copy
{
...
partsProps
.
copy
}
/>
</
Container
>
</
Container
>
);
);
...
...
ui/shared/tx/interpretation/TxInterpretation.tsx
View file @
341acb38
...
@@ -125,7 +125,7 @@ const TxInterpretationElementByType = (
...
@@ -125,7 +125,7 @@ const TxInterpretationElementByType = (
case
'
method
'
:
{
case
'
method
'
:
{
return
(
return
(
<
Badge
<
Badge
color
Schem
e=
{
value
===
'
Multicall
'
?
'
teal
'
:
'
gray
'
}
color
Palett
e=
{
value
===
'
Multicall
'
?
'
teal
'
:
'
gray
'
}
truncated
truncated
ml=
{
1
}
ml=
{
1
}
mr=
{
2
}
mr=
{
2
}
...
...
ui/shared/userOps/UserOpSponsorType.tsx
View file @
341acb38
import
{
Tag
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
UserOpSponsorType
as
TUserOpSponsorType
}
from
'
types/api/userOps
'
;
import
type
{
UserOpSponsorType
as
TUserOpSponsorType
}
from
'
types/api/userOps
'
;
import
{
Badge
}
from
'
toolkit/chakra/badge
'
;
type
Props
=
{
type
Props
=
{
sponsorType
:
TUserOpSponsorType
;
sponsorType
:
TUserOpSponsorType
;
};
};
...
@@ -22,7 +23,7 @@ const UserOpSponsorType = ({ sponsorType }: Props) => {
...
@@ -22,7 +23,7 @@ const UserOpSponsorType = ({ sponsorType }: Props) => {
case
'
wallet_deposit
'
:
case
'
wallet_deposit
'
:
text
=
'
Wallet deposit
'
;
text
=
'
Wallet deposit
'
;
}
}
return
<
Tag
>
{
text
}
</
Tag
>;
return
<
Badge
>
{
text
}
</
Badge
>;
};
};
export
default
UserOpSponsorType
;
export
default
UserOpSponsorType
;
ui/userOp/UserOpCallDataSwitch.tsx
View file @
341acb38
import
{
chakra
,
F
ormLabel
,
FormControl
,
Switch
}
from
'
@chakra-ui/react
'
;
import
{
chakra
,
F
lex
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
{
Switch
}
from
'
toolkit/chakra/switch
'
;
import
Hint
from
'
ui/shared/Hint
'
;
import
Hint
from
'
ui/shared/Hint
'
;
interface
Props
{
interface
Props
{
...
@@ -22,13 +23,23 @@ const UserOpCallDataSwitch = ({ className, initialValue, isDisabled, onChange }:
...
@@ -22,13 +23,23 @@ const UserOpCallDataSwitch = ({ className, initialValue, isDisabled, onChange }:
},
[
onChange
]);
},
[
onChange
]);
return
(
return
(
<
FormControl
className=
{
className
}
display=
"flex"
columnGap=
{
2
}
ml=
"auto"
w=
"fit-content"
>
<
Flex
ml=
"auto"
alignItems=
"center"
gap=
{
2
}
>
<
FormLabel
htmlFor=
"isExternal"
fontSize=
"sm"
lineHeight=
{
5
}
fontWeight=
{
600
}
m=
{
0
}
>
<
Switch
Show external call data
className=
{
className
}
</
FormLabel
>
id=
"call-data-switch"
<
Switch
id=
"isExternal"
isChecked=
{
isChecked
}
isDisabled=
{
isDisabled
}
onChange=
{
handleChange
}
/>
checked=
{
isChecked
}
disabled=
{
isDisabled
}
onCheckedChange=
{
handleChange
}
flexDirection=
"row-reverse"
size=
"md"
gap=
{
2
}
labelProps=
{
{
fontWeight
:
'
600
'
,
fontSize
:
'
sm
'
}
}
>
<
chakra
.
span
hideBelow=
"lg"
>
Show external call data
</
chakra
.
span
>
<
chakra
.
span
hideFrom=
"lg"
>
External call data
</
chakra
.
span
>
</
Switch
>
<
Hint
label=
"Inner call data is a predicted decoded call from this user operation"
/>
<
Hint
label=
"Inner call data is a predicted decoded call from this user operation"
/>
</
F
ormControl
>
</
F
lex
>
);
);
};
};
...
...
ui/userOp/UserOpDetails.tsx
View file @
341acb38
import
{
Grid
,
GridItem
,
Text
,
Link
}
from
'
@chakra-ui/react
'
;
import
{
Grid
,
GridItem
,
Text
}
from
'
@chakra-ui/react
'
;
import
type
{
UseQueryResult
}
from
'
@tanstack/react-query
'
;
import
type
{
UseQueryResult
}
from
'
@tanstack/react-query
'
;
import
BigNumber
from
'
bignumber.js
'
;
import
BigNumber
from
'
bignumber.js
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
{
scroller
,
Element
}
from
'
react-scroll
'
;
import
type
{
UserOp
}
from
'
types/api/userOps
'
;
import
type
{
UserOp
}
from
'
types/api/userOps
'
;
...
@@ -12,12 +11,12 @@ import { WEI, WEI_IN_GWEI } from 'lib/consts';
...
@@ -12,12 +11,12 @@ import { WEI, WEI_IN_GWEI } from 'lib/consts';
import
throwOnResourceLoadError
from
'
lib/errors/throwOnResourceLoadError
'
;
import
throwOnResourceLoadError
from
'
lib/errors/throwOnResourceLoadError
'
;
import
{
space
}
from
'
lib/html-entities
'
;
import
{
space
}
from
'
lib/html-entities
'
;
import
{
currencyUnits
}
from
'
lib/units
'
;
import
{
currencyUnits
}
from
'
lib/units
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
CutLinkDetails
from
'
toolkit/components/CutLink/CutLinkDetails
'
;
import
isCustomAppError
from
'
ui/shared/AppError/isCustomAppError
'
;
import
isCustomAppError
from
'
ui/shared/AppError/isCustomAppError
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
CurrencyValue
from
'
ui/shared/CurrencyValue
'
;
import
CurrencyValue
from
'
ui/shared/CurrencyValue
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
import
*
as
DetailedInfo
from
'
ui/shared/DetailedInfo/DetailedInfo
'
;
import
*
as
DetailedInfo
from
'
ui/shared/DetailedInfo/DetailedInfo
'
;
import
DetailedInfoTimestamp
from
'
ui/shared/DetailedInfo/DetailedInfoTimestamp
'
;
import
DetailedInfoTimestamp
from
'
ui/shared/DetailedInfo/DetailedInfoTimestamp
'
;
import
AddressStringOrParam
from
'
ui/shared/entities/address/AddressStringOrParam
'
;
import
AddressStringOrParam
from
'
ui/shared/entities/address/AddressStringOrParam
'
;
import
BlockEntity
from
'
ui/shared/entities/block/BlockEntity
'
;
import
BlockEntity
from
'
ui/shared/entities/block/BlockEntity
'
;
...
@@ -35,21 +34,9 @@ interface Props {
...
@@ -35,21 +34,9 @@ interface Props {
query
:
UseQueryResult
<
UserOp
,
ResourceError
>
;
query
:
UseQueryResult
<
UserOp
,
ResourceError
>
;
}
}
const
CUT_LINK_NAME
=
'
UserOpDetails__cutLink
'
;
const
UserOpDetails
=
({
query
}:
Props
)
=>
{
const
UserOpDetails
=
({
query
}:
Props
)
=>
{
const
[
isExpanded
,
setIsExpanded
]
=
React
.
useState
(
false
);
const
{
data
,
isPlaceholderData
,
isError
,
error
}
=
query
;
const
{
data
,
isPlaceholderData
,
isError
,
error
}
=
query
;
const
handleCutClick
=
React
.
useCallback
(()
=>
{
setIsExpanded
((
flag
)
=>
!
flag
);
scroller
.
scrollTo
(
CUT_LINK_NAME
,
{
duration
:
500
,
smooth
:
true
,
});
},
[]);
if
(
isError
)
{
if
(
isError
)
{
if
(
error
?.
status
===
400
||
isCustomAppError
(
error
))
{
if
(
error
?.
status
===
400
||
isCustomAppError
(
error
))
{
throwOnResourceLoadError
({
isError
,
error
});
throwOnResourceLoadError
({
isError
,
error
});
...
@@ -76,7 +63,7 @@ const UserOpDetails = ({ query }: Props) => {
...
@@ -76,7 +63,7 @@ const UserOpDetails = ({ query }: Props) => {
User operation hash
User operation hash
</
DetailedInfo
.
ItemLabel
>
</
DetailedInfo
.
ItemLabel
>
<
DetailedInfo
.
ItemValue
>
<
DetailedInfo
.
ItemValue
>
<
Skeleton
isLoaded=
{
!
isPlaceholderData
}
overflow=
"hidden"
>
<
Skeleton
loading=
{
isPlaceholderData
}
overflow=
"hidden"
>
<
UserOpEntity
hash=
{
data
.
hash
}
noIcon
noLink
noCopy=
{
false
}
/>
<
UserOpEntity
hash=
{
data
.
hash
}
noIcon
noLink
noCopy=
{
false
}
/>
</
Skeleton
>
</
Skeleton
>
</
DetailedInfo
.
ItemValue
>
</
DetailedInfo
.
ItemValue
>
...
@@ -113,7 +100,7 @@ const UserOpDetails = ({ query }: Props) => {
...
@@ -113,7 +100,7 @@ const UserOpDetails = ({ query }: Props) => {
wordBreak=
"break-all"
wordBreak=
"break-all"
whiteSpace=
"normal"
whiteSpace=
"normal"
>
>
<
Skeleton
isLoaded=
{
!
isPlaceholderData
}
>
<
Skeleton
loading=
{
isPlaceholderData
}
>
{
data
.
revert_reason
}
{
data
.
revert_reason
}
</
Skeleton
>
</
Skeleton
>
</
DetailedInfo
.
ItemValue
>
</
DetailedInfo
.
ItemValue
>
...
@@ -159,7 +146,7 @@ const UserOpDetails = ({ query }: Props) => {
...
@@ -159,7 +146,7 @@ const UserOpDetails = ({ query }: Props) => {
Gas limit
Gas limit
</
DetailedInfo
.
ItemLabel
>
</
DetailedInfo
.
ItemLabel
>
<
DetailedInfo
.
ItemValue
>
<
DetailedInfo
.
ItemValue
>
<
Skeleton
isLoaded=
{
!
isPlaceholderData
}
>
<
Skeleton
loading=
{
isPlaceholderData
}
>
{
BigNumber
(
data
.
gas
).
toFormat
()
}
{
BigNumber
(
data
.
gas
).
toFormat
()
}
</
Skeleton
>
</
Skeleton
>
</
DetailedInfo
.
ItemValue
>
</
DetailedInfo
.
ItemValue
>
...
@@ -171,7 +158,7 @@ const UserOpDetails = ({ query }: Props) => {
...
@@ -171,7 +158,7 @@ const UserOpDetails = ({ query }: Props) => {
Gas used
Gas used
</
DetailedInfo
.
ItemLabel
>
</
DetailedInfo
.
ItemLabel
>
<
DetailedInfo
.
ItemValue
>
<
DetailedInfo
.
ItemValue
>
<
Skeleton
isLoaded=
{
!
isPlaceholderData
}
>
<
Skeleton
loading=
{
isPlaceholderData
}
>
{
BigNumber
(
data
.
gas_used
).
toFormat
()
}
{
BigNumber
(
data
.
gas_used
).
toFormat
()
}
</
Skeleton
>
</
Skeleton
>
<
Utilization
<
Utilization
...
@@ -214,185 +201,167 @@ const UserOpDetails = ({ query }: Props) => {
...
@@ -214,185 +201,167 @@ const UserOpDetails = ({ query }: Props) => {
{
config
.
features
.
txInterpretation
.
isEnabled
&&
<
UserOpDetailsActions
hash=
{
data
.
hash
}
isUserOpDataLoading=
{
isPlaceholderData
}
/>
}
{
config
.
features
.
txInterpretation
.
isEnabled
&&
<
UserOpDetailsActions
hash=
{
data
.
hash
}
isUserOpDataLoading=
{
isPlaceholderData
}
/>
}
{
/* CUT */
}
<
GridItem
colSpan=
{
{
base
:
undefined
,
lg
:
2
}
}
>
<
Element
name=
{
CUT_LINK_NAME
}
>
<
Skeleton
isLoaded=
{
!
isPlaceholderData
}
mt=
{
6
}
display=
"inline-block"
>
<
Link
fontSize=
"sm"
textDecorationLine=
"underline"
textDecorationStyle=
"dashed"
onClick=
{
handleCutClick
}
>
{
isExpanded
?
'
Hide details
'
:
'
View details
'
}
</
Link
>
</
Skeleton
>
</
Element
>
</
GridItem
>
{
/* ADDITIONAL INFO */
}
{
/* ADDITIONAL INFO */
}
{
isExpanded
&&
!
isPlaceholderData
&&
(
<
CutLinkDetails
loading=
{
isPlaceholderData
}
mt=
{
6
}
gridColumn=
{
{
base
:
undefined
,
lg
:
'
1 / 3
'
}
}
>
<>
<
GridItem
colSpan=
{
{
base
:
undefined
,
lg
:
2
}
}
mt=
{
{
base
:
1
,
lg
:
4
}
}
/>
<
GridItem
colSpan=
{
{
base
:
undefined
,
lg
:
2
}
}
mt=
{
{
base
:
1
,
lg
:
4
}
}
/>
<
DetailedInfo
.
ItemLabel
<
DetailedInfo
.
ItemLabel
hint=
"Gas limit for execution phase"
hint=
"Gas limit for execution phase"
>
>
Call gas limit
Call gas limit
</
DetailedInfo
.
ItemLabel
>
</
DetailedInfo
.
ItemLabel
>
<
DetailedInfo
.
ItemValue
>
<
DetailedInfo
.
ItemValue
>
{
BigNumber
(
data
.
call_gas_limit
).
toFormat
()
}
{
BigNumber
(
data
.
call_gas_limit
).
toFormat
()
}
</
DetailedInfo
.
ItemValue
>
</
DetailedInfo
.
ItemValue
>
<
DetailedInfo
.
ItemLabel
<
DetailedInfo
.
ItemLabel
hint=
"Gas limit for verification phase"
hint=
"Gas limit for verification phase"
>
>
Verification gas limit
Verification gas limit
</
DetailedInfo
.
ItemLabel
>
</
DetailedInfo
.
ItemLabel
>
<
DetailedInfo
.
ItemValue
>
<
DetailedInfo
.
ItemValue
>
{
BigNumber
(
data
.
verification_gas_limit
).
toFormat
()
}
{
BigNumber
(
data
.
verification_gas_limit
).
toFormat
()
}
</
DetailedInfo
.
ItemValue
>
</
DetailedInfo
.
ItemValue
>
<
DetailedInfo
.
ItemLabel
<
DetailedInfo
.
ItemLabel
hint=
"Gas to compensate the bundler"
hint=
"Gas to compensate the bundler"
>
>
Pre-verification gas
Pre-verification gas
</
DetailedInfo
.
ItemLabel
>
</
DetailedInfo
.
ItemLabel
>
<
DetailedInfo
.
ItemValue
>
<
DetailedInfo
.
ItemValue
>
{
BigNumber
(
data
.
pre_verification_gas
).
toFormat
()
}
{
BigNumber
(
data
.
pre_verification_gas
).
toFormat
()
}
</
DetailedInfo
.
ItemValue
>
</
DetailedInfo
.
ItemValue
>
{
!
config
.
UI
.
views
.
tx
.
hiddenFields
?.
gas_fees
&&
(
{
!
config
.
UI
.
views
.
tx
.
hiddenFields
?.
gas_fees
&&
(
<>
<>
<
DetailedInfo
.
ItemLabel
<
DetailedInfo
.
ItemLabel
hint=
"Maximum fee per gas "
hint=
"Maximum fee per gas "
>
>
Max fee per gas
Max fee per gas
</
DetailedInfo
.
ItemLabel
>
</
DetailedInfo
.
ItemLabel
>
<
DetailedInfo
.
ItemValue
>
<
DetailedInfo
.
ItemValue
>
<
Text
>
{
BigNumber
(
data
.
max_fee_per_gas
).
dividedBy
(
WEI
).
toFixed
()
}
{
currencyUnits
.
ether
}
</
Text
>
<
Text
>
{
BigNumber
(
data
.
max_fee_per_gas
).
dividedBy
(
WEI
).
toFixed
()
}
{
currencyUnits
.
ether
}
</
Text
>
<
Text
color=
"text.secondary"
whiteSpace=
"pre"
>
<
Text
variant=
"secondary"
whiteSpace=
"pre"
>
{
space
}
(
{
BigNumber
(
data
.
max_fee_per_gas
).
dividedBy
(
WEI_IN_GWEI
).
toFixed
()
}
{
currencyUnits
.
gwei
}
)
{
space
}
(
{
BigNumber
(
data
.
max_fee_per_gas
).
dividedBy
(
WEI_IN_GWEI
).
toFixed
()
}
{
currencyUnits
.
gwei
}
)
</
Text
>
</
Text
>
</
DetailedInfo
.
ItemValue
>
</
DetailedInfo
.
ItemValue
>
<
DetailedInfo
.
ItemLabel
<
DetailedInfo
.
ItemLabel
hint=
"Maximum priority fee per gas"
hint=
"Maximum priority fee per gas"
>
>
Max priority fee per gas
Max priority fee per gas
</
DetailedInfo
.
ItemLabel
>
</
DetailedInfo
.
ItemLabel
>
<
DetailedInfo
.
ItemValue
>
<
DetailedInfo
.
ItemValue
>
<
Text
>
{
BigNumber
(
data
.
max_priority_fee_per_gas
).
dividedBy
(
WEI
).
toFixed
()
}
{
currencyUnits
.
ether
}
</
Text
>
<
Text
>
{
BigNumber
(
data
.
max_priority_fee_per_gas
).
dividedBy
(
WEI
).
toFixed
()
}
{
currencyUnits
.
ether
}
</
Text
>
<
Text
color=
"text.secondary"
whiteSpace=
"pre"
>
<
Text
variant=
"secondary"
whiteSpace=
"pre"
>
{
space
}
(
{
BigNumber
(
data
.
max_priority_fee_per_gas
).
dividedBy
(
WEI_IN_GWEI
).
toFixed
()
}
{
currencyUnits
.
gwei
}
)
{
space
}
(
{
BigNumber
(
data
.
max_priority_fee_per_gas
).
dividedBy
(
WEI_IN_GWEI
).
toFixed
()
}
{
currencyUnits
.
gwei
}
)
</
Text
>
</
Text
>
</
DetailedInfo
.
ItemValue
>
</
DetailedInfo
.
ItemValue
>
</>
</>
)
}
)
}
<
DetailedInfo
.
ItemDivider
/>
<
DetailedInfo
.
ItemDivider
/>
{
data
.
aggregator
&&
(
{
data
.
aggregator
&&
(
<>
<>
<
DetailedInfo
.
ItemLabel
<
DetailedInfo
.
ItemLabel
hint=
"Helper contract to validate an aggregated signature"
hint=
"Helper contract to validate an aggregated signature"
>
>
Aggregator
Aggregator
</
DetailedInfo
.
ItemLabel
>
</
DetailedInfo
.
ItemLabel
>
<
DetailedInfo
.
ItemValue
>
<
DetailedInfo
.
ItemValue
>
<
AddressStringOrParam
address=
{
data
.
aggregator
}
/>
<
AddressStringOrParam
address=
{
data
.
aggregator
}
/>
</
DetailedInfo
.
ItemValue
>
</
DetailedInfo
.
ItemValue
>
</>
</>
)
}
)
}
{
data
.
aggregator_signature
&&
(
{
data
.
aggregator_signature
&&
(
<>
<>
<
DetailedInfo
.
ItemLabel
<
DetailedInfo
.
ItemLabel
hint=
"Aggregator signature"
hint=
"Aggregator signature"
>
>
Aggregator signature
Aggregator signature
</
DetailedInfo
.
ItemLabel
>
</
DetailedInfo
.
ItemLabel
>
<
DetailedInfo
.
ItemValue
>
<
DetailedInfo
.
ItemValue
>
{
data
.
aggregator_signature
}
{
data
.
aggregator_signature
}
</
DetailedInfo
.
ItemValue
>
</
DetailedInfo
.
ItemValue
>
</>
</>
)
}
)
}
<
DetailedInfo
.
ItemLabel
<
DetailedInfo
.
ItemLabel
hint=
"A node (block builder) that handles User operations"
hint=
"A node (block builder) that handles User operations"
>
>
Bundler
Bundler
</
DetailedInfo
.
ItemLabel
>
</
DetailedInfo
.
ItemLabel
>
<
DetailedInfo
.
ItemValue
>
<
DetailedInfo
.
ItemValue
>
<
AddressStringOrParam
address=
{
data
.
bundler
}
/>
<
AddressStringOrParam
address=
{
data
.
bundler
}
/>
</
DetailedInfo
.
ItemValue
>
</
DetailedInfo
.
ItemValue
>
{
data
.
factory
&&
(
{
data
.
factory
&&
(
<>
<>
<
DetailedInfo
.
ItemLabel
<
DetailedInfo
.
ItemLabel
hint=
"Smart contract that deploys new smart contract wallets for users"
hint=
"Smart contract that deploys new smart contract wallets for users"
>
>
Factory
Factory
</
DetailedInfo
.
ItemLabel
>
</
DetailedInfo
.
ItemLabel
>
<
DetailedInfo
.
ItemValue
>
<
DetailedInfo
.
ItemValue
>
<
AddressStringOrParam
address=
{
data
.
factory
}
/>
<
AddressStringOrParam
address=
{
data
.
factory
}
/>
</
DetailedInfo
.
ItemValue
>
</
DetailedInfo
.
ItemValue
>
</>
</>
)
}
)
}
{
data
.
paymaster
&&
(
{
data
.
paymaster
&&
(
<>
<>
<
DetailedInfo
.
ItemLabel
<
DetailedInfo
.
ItemLabel
hint=
"Contract to sponsor the gas fees for User operations"
hint=
"Contract to sponsor the gas fees for User operations"
>
>
Paymaster
Paymaster
</
DetailedInfo
.
ItemLabel
>
</
DetailedInfo
.
ItemLabel
>
<
DetailedInfo
.
ItemValue
>
<
DetailedInfo
.
ItemValue
>
<
AddressStringOrParam
address=
{
data
.
paymaster
}
/>
<
AddressStringOrParam
address=
{
data
.
paymaster
}
/>
</
DetailedInfo
.
ItemValue
>
</
DetailedInfo
.
ItemValue
>
</>
</>
)
}
)
}
<
DetailedInfo
.
ItemLabel
<
DetailedInfo
.
ItemLabel
hint=
"Type of the gas fees sponsor"
hint=
"Type of the gas fees sponsor"
>
>
Sponsor type
Sponsor type
</
DetailedInfo
.
ItemLabel
>
</
DetailedInfo
.
ItemLabel
>
<
DetailedInfo
.
ItemValue
>
<
DetailedInfo
.
ItemValue
>
<
UserOpSponsorType
sponsorType=
{
data
.
sponsor_type
}
/>
<
UserOpSponsorType
sponsorType=
{
data
.
sponsor_type
}
/>
</
DetailedInfo
.
ItemValue
>
</
DetailedInfo
.
ItemValue
>
<
DetailedInfo
.
ItemDivider
/>
<
DetailedInfo
.
ItemDivider
/>
<
DetailedInfo
.
ItemLabel
<
DetailedInfo
.
ItemLabel
hint=
"Used to validate a User operation along with the nonce during verification"
hint=
"Used to validate a User operation along with the nonce during verification"
>
>
Signature
Signature
</
DetailedInfo
.
ItemLabel
>
</
DetailedInfo
.
ItemLabel
>
<
DetailedInfo
.
ItemValue
<
DetailedInfo
.
ItemValue
wordBreak=
"break-all"
wordBreak=
"break-all"
whiteSpace=
"normal"
whiteSpace=
"normal"
>
>
{
data
.
signature
}
{
data
.
signature
}
</
DetailedInfo
.
ItemValue
>
</
DetailedInfo
.
ItemValue
>
<
DetailedInfo
.
ItemLabel
<
DetailedInfo
.
ItemLabel
hint=
"Anti-replay protection; also used as the salt for first-time account creation"
hint=
"Anti-replay protection; also used as the salt for first-time account creation"
>
>
Nonce
Nonce
</
DetailedInfo
.
ItemLabel
>
</
DetailedInfo
.
ItemLabel
>
<
DetailedInfo
.
ItemValue
<
DetailedInfo
.
ItemValue
wordBreak=
"break-all"
wordBreak=
"break-all"
whiteSpace=
"normal"
whiteSpace=
"normal"
>
>
{
data
.
nonce
}
{
data
.
nonce
}
</
DetailedInfo
.
ItemValue
>
</
DetailedInfo
.
ItemValue
>
<
UserOpCallData
data=
{
data
}
/>
<
UserOpCallData
data=
{
data
}
/>
<
UserOpDecodedCallData
data=
{
data
}
/>
<
UserOpDecodedCallData
data=
{
data
}
/>
</
CutLinkDetails
>
</>
)
}
</
Grid
>
</
Grid
>
);
);
};
};
...
...
ui/userOp/UserOpRaw.tsx
View file @
341acb38
...
@@ -2,7 +2,7 @@ import React from 'react';
...
@@ -2,7 +2,7 @@ import React from 'react';
import
type
{
UserOp
}
from
'
types/api/userOps
'
;
import
type
{
UserOp
}
from
'
types/api/userOps
'
;
import
Skeleton
from
'
ui/shared/chakra/S
keleton
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/s
keleton
'
;
import
RawDataSnippet
from
'
ui/shared/RawDataSnippet
'
;
import
RawDataSnippet
from
'
ui/shared/RawDataSnippet
'
;
// order is taken from the ERC-4337 standard
// order is taken from the ERC-4337 standard
...
@@ -27,7 +27,7 @@ const UserOpRaw = ({ rawData, isLoading }: Props) => {
...
@@ -27,7 +27,7 @@ const UserOpRaw = ({ rawData, isLoading }: Props) => {
return
res
;
return
res
;
},
{}
as
UserOp
[
'
raw
'
]),
undefined
,
4
);
},
{}
as
UserOp
[
'
raw
'
]),
undefined
,
4
);
return
<
Skeleton
isLoaded=
{
!
isLoading
}
><
RawDataSnippet
data=
{
text
}
/></
Skeleton
>;
return
<
Skeleton
loading=
{
isLoading
}
><
RawDataSnippet
data=
{
text
}
/></
Skeleton
>;
};
};
export
default
UserOpRaw
;
export
default
UserOpRaw
;
ui/userOp/UserOpSubHeading.tsx
View file @
341acb38
import
{
Flex
,
Link
}
from
'
@chakra-ui/react
'
;
import
{
Flex
}
from
'
@chakra-ui/react
'
;
// import type { UseQueryResult } from '@tanstack/react-query';
// import type { UseQueryResult } from '@tanstack/react-query';
import
React
from
'
react
'
;
import
React
from
'
react
'
;
...
@@ -8,6 +8,7 @@ import config from 'configs/app';
...
@@ -8,6 +8,7 @@ import config from 'configs/app';
// import type { ResourceError } from 'lib/api/resources';
// import type { ResourceError } from 'lib/api/resources';
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
{
TX_INTERPRETATION
}
from
'
stubs/txInterpretation
'
;
import
{
TX_INTERPRETATION
}
from
'
stubs/txInterpretation
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
{
TX_ACTIONS_BLOCK_ID
}
from
'
ui/shared/DetailedInfo/DetailedInfoActionsWrapper
'
;
import
{
TX_ACTIONS_BLOCK_ID
}
from
'
ui/shared/DetailedInfo/DetailedInfoActionsWrapper
'
;
import
UserOpEntity
from
'
ui/shared/entities/userOp/UserOpEntity
'
;
import
UserOpEntity
from
'
ui/shared/entities/userOp/UserOpEntity
'
;
import
TxInterpretation
from
'
ui/shared/tx/interpretation/TxInterpretation
'
;
import
TxInterpretation
from
'
ui/shared/tx/interpretation/TxInterpretation
'
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment