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
a86ee441
Commit
a86ee441
authored
Feb 05, 2025
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
tx details tab
parent
a19110b6
Changes
46
Show whitespace changes
Inline
Side-by-side
Showing
46 changed files
with
685 additions
and
371 deletions
+685
-371
eslint.config.mjs
eslint.config.mjs
+2
-1
[hash].tsx
pages/tx/[hash].tsx
+2
-2
index.tsx
pages/txs/index.tsx
+2
-2
menu.tsx
toolkit/chakra/menu.tsx
+124
-0
skeleton.tsx
toolkit/chakra/skeleton.tsx
+6
-2
CutLink.tsx
toolkit/components/CutLink/CutLink.tsx
+13
-2
semanticTokens.ts
toolkit/theme/foundations/semanticTokens.ts
+7
-0
index.ts
toolkit/theme/recipes/index.ts
+2
-0
menu.recipe.ts
toolkit/theme/recipes/menu.recipe.ts
+105
-0
AddressVerificationStepAddress.tsx
...ressVerification/steps/AddressVerificationStepAddress.tsx
+2
-3
Chakra.tsx
ui/pages/Chakra.tsx
+3
-0
Transaction.tsx
ui/pages/Transaction.tsx
+27
-27
Transactions.tsx
ui/pages/Transactions.tsx
+8
-6
AccountActionsMenu.tsx
ui/shared/AccountActionsMenu/AccountActionsMenu.tsx
+23
-27
MetadataUpdateMenuItem.tsx
...hared/AccountActionsMenu/items/MetadataUpdateMenuItem.tsx
+3
-4
PrivateTagMenuItem.tsx
ui/shared/AccountActionsMenu/items/PrivateTagMenuItem.tsx
+5
-5
PublicTagMenuItem.tsx
ui/shared/AccountActionsMenu/items/PublicTagMenuItem.tsx
+3
-3
TokenInfoMenuItem.tsx
ui/shared/AccountActionsMenu/items/TokenInfoMenuItem.tsx
+6
-5
ButtonItem.tsx
ui/shared/AccountActionsMenu/parts/ButtonItem.tsx
+7
-5
MenuItem.tsx
ui/shared/AccountActionsMenu/parts/MenuItem.tsx
+5
-3
types.ts
ui/shared/AccountActionsMenu/types.ts
+0
-1
ContainerWithScrollY.tsx
ui/shared/ContainerWithScrollY.tsx
+2
-4
DetailsInfoItemDivider.tsx
ui/shared/DetailsInfoItemDivider.tsx
+2
-2
RawInputData.tsx
ui/shared/RawInputData.tsx
+27
-9
TestnetWarning.tsx
ui/shared/alerts/TestnetWarning.tsx
+3
-5
Menu.tsx
ui/shared/chakra/Menu.tsx
+0
-10
LogDecodedInputDataHeader.tsx
ui/shared/logs/LogDecodedInputDataHeader.tsx
+8
-9
LogDecodedInputDataTable.tsx
ui/shared/logs/LogDecodedInputDataTable.tsx
+7
-9
TxInterpretation.tsx
ui/shared/tx/interpretation/TxInterpretation.tsx
+13
-12
Alerts.tsx
ui/showcases/Alerts.tsx
+9
-0
Button.tsx
ui/showcases/Button.tsx
+14
-1
Menu.tsx
ui/showcases/Menu.tsx
+56
-0
TxAllowedPeekers.tsx
ui/tx/TxAllowedPeekers.tsx
+9
-3
TxDetailsDegraded.tsx
ui/tx/TxDetailsDegraded.tsx
+3
-3
TxSocketAlert.tsx
ui/tx/TxSocketAlert.tsx
+7
-2
TxSubHeading.tsx
ui/tx/TxSubHeading.tsx
+5
-3
TxDetailsFeePerGas.tsx
ui/tx/details/TxDetailsFeePerGas.tsx
+2
-2
TxDetailsGasPrice.tsx
ui/tx/details/TxDetailsGasPrice.tsx
+4
-4
TxDetailsOther.tsx
ui/tx/details/TxDetailsOther.tsx
+4
-4
TxDetailsTokenTransfers.tsx
ui/tx/details/TxDetailsTokenTransfers.tsx
+5
-6
TxDetailsWithdrawalStatus.tsx
ui/tx/details/TxDetailsWithdrawalStatus.tsx
+2
-1
TxInfo.tsx
ui/tx/details/TxInfo.tsx
+134
-162
TxInfoScrollFees.tsx
ui/tx/details/TxInfoScrollFees.tsx
+8
-8
TxRevertReason.tsx
ui/tx/details/TxRevertReason.tsx
+2
-4
useTxQuery.tsx
ui/tx/useTxQuery.tsx
+3
-8
TxsTableItem.tsx
ui/txs/TxsTableItem.tsx
+1
-2
No files found.
eslint.config.mjs
View file @
a86ee441
...
...
@@ -36,8 +36,9 @@ const RESTRICTED_MODULES = {
'
Image
'
,
'
Popover
'
,
'
PopoverTrigger
'
,
'
PopoverContent
'
,
'
PopoverBody
'
,
'
PopoverFooter
'
,
'
DrawerRoot
'
,
'
DrawerBody
'
,
'
DrawerContent
'
,
'
DrawerOverlay
'
,
'
DrawerBackdrop
'
,
'
DrawerTrigger
'
,
'
Drawer
'
,
'
Alert
'
,
'
AlertIcon
'
,
'
AlertTitle
'
,
'
AlertDescription
'
,
'
Heading
'
,
'
Badge
'
,
'
Tabs
'
,
'
Heading
'
,
'
Badge
'
,
'
Tabs
'
,
'
Show
'
,
'
Hide
'
,
'
Table
'
,
'
TableRoot
'
,
'
TableBody
'
,
'
TableHeader
'
,
'
TableRow
'
,
'
TableCell
'
,
'
Menu
'
,
'
MenuRoot
'
,
'
MenuTrigger
'
,
'
MenuContent
'
,
'
MenuItem
'
,
'
MenuTriggerItem
'
,
'
MenuRadioItemGroup
'
,
'
MenuContextTrigger
'
,
],
message
:
'
Please use corresponding component or hook from ui/shared/chakra component instead
'
,
},
...
...
pages/tx/[hash].tsx
View file @
a86ee441
...
...
@@ -5,12 +5,12 @@ import React from 'react';
import
type
{
Props
}
from
'
nextjs/getServerSideProps
'
;
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
//
const Transaction = dynamic(() => import('ui/pages/Transaction'), { ssr: false });
const
Transaction
=
dynamic
(()
=>
import
(
'
ui/pages/Transaction
'
),
{
ssr
:
false
});
const
Page
:
NextPage
<
Props
>
=
(
props
:
Props
)
=>
{
return
(
<
PageNextJs
pathname=
"/tx/[hash]"
query=
{
props
.
query
}
>
{
/* <Transaction/> */
}
<
Transaction
/>
</
PageNextJs
>
);
};
...
...
pages/txs/index.tsx
View file @
a86ee441
...
...
@@ -4,12 +4,12 @@ import React from 'react';
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
//
const Transactions = dynamic(() => import('ui/pages/Transactions'), { ssr: false });
const
Transactions
=
dynamic
(()
=>
import
(
'
ui/pages/Transactions
'
),
{
ssr
:
false
});
const
Page
:
NextPage
=
()
=>
{
return
(
<
PageNextJs
pathname=
"/txs"
>
{
/* <Transactions/> */
}
<
Transactions
/>
</
PageNextJs
>
);
};
...
...
toolkit/chakra/menu.tsx
0 → 100644
View file @
a86ee441
'
use client
'
;
import
{
AbsoluteCenter
,
Menu
as
ChakraMenu
,
Portal
}
from
'
@chakra-ui/react
'
;
import
*
as
React
from
'
react
'
;
import
{
LuCheck
,
LuChevronRight
}
from
'
react-icons/lu
'
;
interface
MenuContentProps
extends
ChakraMenu
.
ContentProps
{
portalled
?:
boolean
;
portalRef
?:
React
.
RefObject
<
HTMLElement
>
;
}
export
const
MenuContent
=
React
.
forwardRef
<
HTMLDivElement
,
MenuContentProps
>
(
function
MenuContent
(
props
,
ref
)
{
const
{
portalled
=
true
,
portalRef
,
...
rest
}
=
props
;
return
(
<
Portal
disabled=
{
!
portalled
}
container=
{
portalRef
}
>
<
ChakraMenu
.
Positioner
>
<
ChakraMenu
.
Content
ref=
{
ref
}
{
...
rest
}
/>
</
ChakraMenu
.
Positioner
>
</
Portal
>
);
},
);
export
const
MenuArrow
=
React
.
forwardRef
<
HTMLDivElement
,
ChakraMenu
.
ArrowProps
>
(
function
MenuArrow
(
props
,
ref
)
{
return
(
<
ChakraMenu
.
Arrow
ref=
{
ref
}
{
...
props
}
>
<
ChakraMenu
.
ArrowTip
/>
</
ChakraMenu
.
Arrow
>
);
});
export
const
MenuCheckboxItem
=
React
.
forwardRef
<
HTMLDivElement
,
ChakraMenu
.
CheckboxItemProps
>
(
function
MenuCheckboxItem
(
props
,
ref
)
{
return
(
<
ChakraMenu
.
CheckboxItem
ps=
"8"
ref=
{
ref
}
{
...
props
}
>
<
AbsoluteCenter
axis=
"horizontal"
insetStart=
"4"
asChild
>
<
ChakraMenu
.
ItemIndicator
>
<
LuCheck
/>
</
ChakraMenu
.
ItemIndicator
>
</
AbsoluteCenter
>
{
props
.
children
}
</
ChakraMenu
.
CheckboxItem
>
);
});
export
const
MenuRadioItem
=
React
.
forwardRef
<
HTMLDivElement
,
ChakraMenu
.
RadioItemProps
>
(
function
MenuRadioItem
(
props
,
ref
)
{
const
{
children
,
...
rest
}
=
props
;
return
(
<
ChakraMenu
.
RadioItem
ps=
"8"
ref=
{
ref
}
{
...
rest
}
>
<
AbsoluteCenter
axis=
"horizontal"
insetStart=
"4"
asChild
>
<
ChakraMenu
.
ItemIndicator
>
<
LuCheck
/>
</
ChakraMenu
.
ItemIndicator
>
</
AbsoluteCenter
>
<
ChakraMenu
.
ItemText
>
{
children
}
</
ChakraMenu
.
ItemText
>
</
ChakraMenu
.
RadioItem
>
);
});
export
const
MenuItemGroup
=
React
.
forwardRef
<
HTMLDivElement
,
ChakraMenu
.
ItemGroupProps
>
(
function
MenuItemGroup
(
props
,
ref
)
{
const
{
title
,
children
,
...
rest
}
=
props
;
return
(
<
ChakraMenu
.
ItemGroup
ref=
{
ref
}
{
...
rest
}
>
{
title
&&
(
<
ChakraMenu
.
ItemGroupLabel
userSelect=
"none"
>
{
title
}
</
ChakraMenu
.
ItemGroupLabel
>
)
}
{
children
}
</
ChakraMenu
.
ItemGroup
>
);
});
export
interface
MenuTriggerItemProps
extends
ChakraMenu
.
ItemProps
{
startIcon
?:
React
.
ReactNode
;
}
export
const
MenuTriggerItem
=
React
.
forwardRef
<
HTMLDivElement
,
MenuTriggerItemProps
>
(
function
MenuTriggerItem
(
props
,
ref
)
{
const
{
startIcon
,
children
,
...
rest
}
=
props
;
return
(
<
ChakraMenu
.
TriggerItem
ref=
{
ref
}
{
...
rest
}
>
{
startIcon
}
{
children
}
<
LuChevronRight
/>
</
ChakraMenu
.
TriggerItem
>
);
});
export
const
MenuRadioItemGroup
=
ChakraMenu
.
RadioItemGroup
;
export
const
MenuContextTrigger
=
ChakraMenu
.
ContextTrigger
;
export
const
MenuRoot
=
(
props
:
ChakraMenu
.
RootProps
)
=>
{
const
{
lazyMount
=
true
,
unmountOnExit
=
true
,
...
rest
}
=
props
;
const
positioning
=
{
placement
:
'
bottom-start
'
as
const
,
...
props
.
positioning
,
offset
:
{
mainAxis
:
4
,
...
props
.
positioning
?.
offset
,
},
};
return
<
ChakraMenu
.
Root
{
...
rest
}
positioning=
{
positioning
}
lazyMount=
{
lazyMount
}
unmountOnExit=
{
unmountOnExit
}
/>;
};
export
const
MenuSeparator
=
ChakraMenu
.
Separator
;
export
const
MenuItem
=
ChakraMenu
.
Item
;
export
const
MenuItemText
=
ChakraMenu
.
ItemText
;
export
const
MenuItemCommand
=
ChakraMenu
.
ItemCommand
;
export
const
MenuTrigger
=
ChakraMenu
.
Trigger
;
toolkit/chakra/skeleton.tsx
View file @
a86ee441
...
...
@@ -44,9 +44,13 @@ export const SkeletonText = React.forwardRef<HTMLDivElement, SkeletonTextProps>(
},
);
export
const
Skeleton
=
React
.
forwardRef
<
HTMLDivElement
,
ChakraSkeletonProps
>
(
export
interface
SkeletonProps
extends
Omit
<
ChakraSkeletonProps
,
'
loading
'
>
{
loading
:
boolean
|
undefined
;
}
export
const
Skeleton
=
React
.
forwardRef
<
HTMLDivElement
,
SkeletonProps
>
(
function
Skeleton
(
props
,
ref
)
{
const
{
loading
=
tru
e
,
...
rest
}
=
props
;
const
{
loading
=
fals
e
,
...
rest
}
=
props
;
return
<
ChakraSkeleton
loading=
{
loading
}
{
...
(
loading
?
{
'
data
-
loading
':
true
}
:
{})
}
{
...
rest
}
ref=
{
ref
}
/>;
},
);
toolkit/components/CutLink/CutLink.tsx
View file @
a86ee441
import
React
from
'
react
'
;
import
{
scroller
,
Element
}
from
'
react-scroll
'
;
import
useUpdateEffect
from
'
lib/hooks/useUpdateEffect
'
;
import
type
{
LinkProps
}
from
'
toolkit/chakra/link
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
...
...
@@ -8,14 +9,15 @@ interface Props extends LinkProps {
children
:
React
.
ReactNode
;
id
?:
string
;
onClick
?:
()
=>
void
;
isExpanded
?:
boolean
;
}
const
ID
=
'
CutLink
'
;
const
CutLink
=
(
props
:
Props
)
=>
{
const
{
children
,
id
=
ID
,
onClick
,
...
rest
}
=
props
;
const
{
children
,
id
=
ID
,
onClick
,
isExpanded
:
isExpandedProp
=
false
,
...
rest
}
=
props
;
const
[
isExpanded
,
setIsExpanded
]
=
React
.
useState
(
false
);
const
[
isExpanded
,
setIsExpanded
]
=
React
.
useState
(
isExpandedProp
);
const
handleClick
=
React
.
useCallback
(()
=>
{
setIsExpanded
((
flag
)
=>
!
flag
);
...
...
@@ -26,6 +28,14 @@ const CutLink = (props: Props) => {
onClick
?.();
},
[
id
,
onClick
]);
useUpdateEffect
(()
=>
{
setIsExpanded
(
isExpandedProp
);
isExpandedProp
&&
scroller
.
scrollTo
(
id
,
{
duration
:
500
,
smooth
:
true
,
});
},
[
isExpandedProp
,
id
]);
const
text
=
isExpanded
?
'
Hide details
'
:
'
View details
'
;
return
(
...
...
@@ -34,6 +44,7 @@ const CutLink = (props: Props) => {
textStyle=
"sm"
textDecorationLine=
"underline"
textDecorationStyle=
"dashed"
w=
"fit-content"
onClick=
{
handleClick
}
asChild
{
...
rest
}
...
...
toolkit/theme/foundations/semanticTokens.ts
View file @
a86ee441
...
...
@@ -260,6 +260,13 @@ const semanticTokens: ThemingConfig['semanticTokens'] = {
},
},
},
menu
:
{
item
:
{
bg
:
{
highlighted
:
{
value
:
{
_light
:
'
{colors.blue.50}
'
,
_dark
:
'
{colors.whiteAlpha.100}
'
}
},
},
},
},
spinner
:
{
track
:
{
DEFAULT
:
{
value
:
{
_light
:
'
{colors.blackAlpha.200}
'
,
_dark
:
'
{colors.whiteAlpha.200}
'
}
},
...
...
toolkit/theme/recipes/index.ts
View file @
a86ee441
...
...
@@ -8,6 +8,7 @@ import { recipe as drawer } from './drawer.recipe';
import
{
recipe
as
field
}
from
'
./field.recipe
'
;
import
{
recipe
as
input
}
from
'
./input.recipe
'
;
import
{
recipe
as
link
}
from
'
./link.recipe
'
;
import
{
recipe
as
menu
}
from
'
./menu.recipe
'
;
import
{
recipe
as
nativeSelect
}
from
'
./native-select.recipe
'
;
import
{
recipe
as
pinInput
}
from
'
./pin-input.recipe
'
;
import
{
recipe
as
popover
}
from
'
./popover.recipe
'
;
...
...
@@ -40,6 +41,7 @@ export const slotRecipes = {
dialog
,
drawer
,
field
,
menu
,
nativeSelect
,
pinInput
,
popover
,
...
...
toolkit/theme/recipes/menu.recipe.ts
0 → 100644
View file @
a86ee441
import
{
defineSlotRecipe
}
from
'
@chakra-ui/react
'
;
export
const
recipe
=
defineSlotRecipe
({
slots
:
[
'
content
'
,
'
item
'
,
'
itemText
'
,
'
itemGroupLabel
'
,
'
indicator
'
,
'
itemCommand
'
,
'
separator
'
],
base
:
{
content
:
{
outline
:
0
,
bg
:
'
popover,bg
'
,
boxShadow
:
'
popover
'
,
color
:
'
initial
'
,
maxHeight
:
'
var(--available-height)
'
,
'
--menu-z-index
'
:
'
zIndex.dropdown
'
,
zIndex
:
'
calc(var(--menu-z-index) + var(--layer-index, 0))
'
,
borderRadius
:
'
md
'
,
overflow
:
'
hidden
'
,
overflowY
:
'
auto
'
,
_open
:
{
animationStyle
:
'
slide-fade-in
'
,
animationDuration
:
'
fast
'
,
},
_closed
:
{
animationStyle
:
'
slide-fade-out
'
,
animationDuration
:
'
faster
'
,
},
},
item
:
{
textDecoration
:
'
none
'
,
color
:
'
initial
'
,
userSelect
:
'
none
'
,
borderRadius
:
'
none
'
,
width
:
'
100%
'
,
display
:
'
flex
'
,
cursor
:
'
pointer
'
,
alignItems
:
'
center
'
,
textAlign
:
'
start
'
,
position
:
'
relative
'
,
flex
:
'
0 0 auto
'
,
outline
:
0
,
_disabled
:
{
layerStyle
:
'
disabled
'
,
},
},
itemText
:
{
flex
:
'
1
'
,
},
itemGroupLabel
:
{
px
:
'
2
'
,
py
:
'
1.5
'
,
fontWeight
:
'
semibold
'
,
textStyle
:
'
sm
'
,
},
indicator
:
{
display
:
'
inline-flex
'
,
alignItems
:
'
center
'
,
justifyContent
:
'
center
'
,
flexShrink
:
'
0
'
,
},
itemCommand
:
{
opacity
:
'
0.6
'
,
textStyle
:
'
xs
'
,
ms
:
'
auto
'
,
ps
:
'
4
'
,
letterSpacing
:
'
widest
'
,
},
separator
:
{
height
:
'
1px
'
,
bg
:
'
bg.muted
'
,
my
:
'
1
'
,
mx
:
'
-1
'
,
},
},
variants
:
{
variant
:
{
subtle
:
{
item
:
{
_highlighted
:
{
bg
:
'
menu.item.bg.highlighted
'
,
},
},
},
},
size
:
{
md
:
{
content
:
{
minW
:
'
150px
'
,
py
:
'
2
'
,
px
:
'
0
'
,
},
item
:
{
gap
:
'
2
'
,
textStyle
:
'
md
'
,
py
:
'
2
'
,
px
:
'
4
'
,
},
},
},
},
defaultVariants
:
{
size
:
'
md
'
,
variant
:
'
subtle
'
,
},
});
ui/addressVerification/steps/AddressVerificationStepAddress.tsx
View file @
a86ee441
...
...
@@ -16,10 +16,9 @@ import { route } from 'nextjs-routes';
import
config
from
'
configs/app
'
;
import
type
{
ResourceError
}
from
'
lib/api/resources
'
;
import
useApiFetch
from
'
lib/api/useApiFetch
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
FormFieldAddress
from
'
ui/shared/forms/fields/FormFieldAddress
'
;
import
LinkInternal
from
'
ui/shared/links/LinkInternal
'
;
import
AdminSupportText
from
'
ui/shared/texts/AdminSupportText
'
;
type
Fields
=
RootFields
&
AddressVerificationFormFirstStepFields
;
interface
Props
{
...
...
@@ -85,7 +84,7 @@ const AddressVerificationStepAddress = ({ defaultAddress, onContinue }: Props) =
return
(
<
Box
>
<
span
>
The contract source code you entered is not yet verified. Please follow these steps to
</
span
>
<
Link
Internal
href=
{
href
}
>
verify the contract
</
LinkInternal
>
<
Link
href=
{
href
}
>
verify the contract
</
Link
>
<
span
>
.
</
span
>
</
Box
>
);
...
...
ui/pages/Chakra.tsx
View file @
a86ee441
...
...
@@ -25,6 +25,7 @@ import AlertsShowcase from 'ui/showcases/Alerts';
import
BadgesShowcase
from
'
ui/showcases/Badges
'
;
import
ButtonShowcase
from
'
ui/showcases/Button
'
;
import
LinksShowcase
from
'
ui/showcases/Links
'
;
import
MenusShowcase
from
'
ui/showcases/Menu
'
;
import
PaginationShowcase
from
'
ui/showcases/Pagination
'
;
import
SelectsShowcase
from
'
ui/showcases/Select
'
;
import
TabsShowcase
from
'
ui/showcases/Tabs
'
;
...
...
@@ -50,6 +51,7 @@ const ChakraShowcases = () => {
<
TabsTrigger
value=
"badges"
>
Badges
</
TabsTrigger
>
<
TabsTrigger
value=
"buttons"
>
Buttons
</
TabsTrigger
>
<
TabsTrigger
value=
"links"
>
Links
</
TabsTrigger
>
<
TabsTrigger
value=
"menus"
>
Menus
</
TabsTrigger
>
<
TabsTrigger
value=
"pagination"
>
Pagination
</
TabsTrigger
>
<
TabsTrigger
value=
"selects"
>
Selects
</
TabsTrigger
>
<
TabsTrigger
value=
"tabs"
>
Tabs
</
TabsTrigger
>
...
...
@@ -62,6 +64,7 @@ const ChakraShowcases = () => {
<
BadgesShowcase
/>
<
ButtonShowcase
/>
<
LinksShowcase
/>
<
MenusShowcase
/>
<
TabsShowcase
/>
<
PaginationShowcase
/>
<
SelectsShowcase
/>
...
...
ui/pages/Transaction.tsx
View file @
a86ee441
...
...
@@ -8,12 +8,12 @@ import { useAppContext } from 'lib/contexts/app';
import
throwOnResourceLoadError
from
'
lib/errors/throwOnResourceLoadError
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
{
publicClient
}
from
'
lib/web3/client
'
;
import
RoutedTabs
from
'
toolkit/components/RoutedTabs/RoutedTabs
'
;
import
RoutedTabsSkeleton
from
'
toolkit/components/RoutedTabs/RoutedTabsSkeleton
'
;
import
TextAd
from
'
ui/shared/ad/TextAd
'
;
import
isCustomAppError
from
'
ui/shared/AppError/isCustomAppError
'
;
import
EntityTags
from
'
ui/shared/EntityTags/EntityTags
'
;
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
TxAssetFlows
from
'
ui/tx/TxAssetFlows
'
;
import
TxBlobs
from
'
ui/tx/TxBlobs
'
;
...
...
@@ -52,34 +52,34 @@ const TransactionPageContent = () => {
title
:
config
.
features
.
suave
.
isEnabled
&&
data
?.
wrapped
?
'
Confidential compute tx details
'
:
'
Details
'
,
component
:
detailsComponent
,
},
txInterpretation
.
isEnabled
&&
txInterpretation
.
provider
===
'
noves
'
?
{
id
:
'
asset_flows
'
,
title
:
'
Asset Flows
'
,
component
:
<
TxAssetFlows
hash=
{
hash
}
/>
}
:
undefined
,
config
.
features
.
suave
.
isEnabled
&&
data
?.
wrapped
?
{
id
:
'
wrapped
'
,
title
:
'
Regular tx details
'
,
component
:
<
TxDetailsWrapped
data=
{
data
.
wrapped
}
/>
}
:
undefined
,
{
id
:
'
token_transfers
'
,
title
:
'
Token transfers
'
,
component
:
<
TxTokenTransfer
txQuery=
{
txQuery
}
/>
},
config
.
features
.
userOps
.
isEnabled
?
{
id
:
'
user_ops
'
,
title
:
'
User operations
'
,
component
:
<
TxUserOps
txQuery=
{
txQuery
}
/>
}
:
undefined
,
{
id
:
'
internal
'
,
title
:
'
Internal txns
'
,
component
:
<
TxInternals
txQuery=
{
txQuery
}
/>
},
config
.
features
.
dataAvailability
.
isEnabled
&&
txQuery
.
data
?.
blob_versioned_hashes
?.
length
?
{
id
:
'
blobs
'
,
title
:
'
Blobs
'
,
component
:
<
TxBlobs
txQuery=
{
txQuery
}
/>
}
:
undefined
,
{
id
:
'
logs
'
,
title
:
'
Logs
'
,
component
:
<
TxLogs
txQuery=
{
txQuery
}
/>
},
{
id
:
'
state
'
,
title
:
'
State
'
,
component
:
<
TxState
txQuery=
{
txQuery
}
/>
},
{
id
:
'
raw_trace
'
,
title
:
'
Raw trace
'
,
component
:
<
TxRawTrace
txQuery=
{
txQuery
}
/>
},
//
txInterpretation.isEnabled && txInterpretation.provider === 'noves' ?
//
{ id: 'asset_flows', title: 'Asset Flows', component: <TxAssetFlows hash={ hash }/> } :
//
undefined,
//
config.features.suave.isEnabled && data?.wrapped ?
//
{ id: 'wrapped', title: 'Regular tx details', component: <TxDetailsWrapped data={ data.wrapped }/> } :
//
undefined,
//
{ id: 'token_transfers', title: 'Token transfers', component: <TxTokenTransfer txQuery={ txQuery }/> },
//
config.features.userOps.isEnabled ?
//
{ id: 'user_ops', title: 'User operations', component: <TxUserOps txQuery={ txQuery }/> } :
//
undefined,
//
{ id: 'internal', title: 'Internal txns', component: <TxInternals txQuery={ txQuery }/> },
//
config.features.dataAvailability.isEnabled && txQuery.data?.blob_versioned_hashes?.length ?
//
{ id: 'blobs', title: 'Blobs', component: <TxBlobs txQuery={ txQuery }/> } :
//
undefined,
//
{ id: 'logs', title: 'Logs', component: <TxLogs txQuery={ txQuery }/> },
//
{ id: 'state', title: 'State', component: <TxState txQuery={ txQuery }/> },
//
{ id: 'raw_trace', title: 'Raw trace', component: <TxRawTrace txQuery={ txQuery }/> },
].
filter
(
Boolean
);
})();
const
tabIndex
=
useTabIndexFromQuery
(
tabs
);
const
tags
=
(
<
EntityTags
isLoading=
{
isPlaceholderData
}
tags=
{
data
?.
transaction_tag
?
[
{
slug
:
data
.
transaction_tag
,
name
:
data
.
transaction_tag
,
tagType
:
'
private_tag
'
as
const
}
]
:
[]
}
/>
);
//
const tags = (
//
<EntityTags
//
isLoading={ isPlaceholderData }
// tags={ data?.transaction_tag ? [ { slug: data.transaction_tag, name: data.transaction_tag, tagType: 'private_tag' as const, ordinal: 10
} ] : [] }
//
/>
//
);
const
backLink
=
React
.
useMemo
(()
=>
{
const
hasGoBackLink
=
appProps
.
referrer
&&
appProps
.
referrer
.
includes
(
'
/txs
'
);
...
...
@@ -100,7 +100,7 @@ const TransactionPageContent = () => {
if
(
isPlaceholderData
&&
!
showDegradedView
)
{
return
(
<>
<
TabsSkeleton
tabs=
{
tabs
}
mt=
{
6
}
/>
<
Routed
TabsSkeleton
tabs=
{
tabs
}
mt=
{
6
}
/>
{
tabs
[
tabIndex
]?.
component
}
</>
);
...
...
@@ -121,7 +121,7 @@ const TransactionPageContent = () => {
<
PageTitle
title=
"Transaction details"
backLink=
{
backLink
}
contentAfter=
{
tags
}
//
contentAfter={ tags }
secondRow=
{
titleSecondRow
}
/>
{
content
}
...
...
ui/pages/Transactions.tsx
View file @
a86ee441
...
...
@@ -5,6 +5,8 @@ import React from 'react';
import
type
{
RoutedTab
}
from
'
ui/shared/Tabs/types
'
;
import
{
route
}
from
'
nextjs-routes
'
;
import
config
from
'
configs/app
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useNewTxsSocket
from
'
lib/hooks/useNewTxsSocket
'
;
...
...
@@ -12,12 +14,12 @@ import getNetworkValidationActionText from 'lib/networks/getNetworkValidationAct
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
{
TX
}
from
'
stubs/tx
'
;
import
{
generateListStub
}
from
'
stubs/utils
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
RoutedTabs
from
'
toolkit/components/RoutedTabs/RoutedTabs
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
LinkInternal
from
'
ui/shared/links/LinkInternal
'
;
import
PageTitle
from
'
ui/shared/Page/PageTitle
'
;
import
Pagination
from
'
ui/shared/pagination/Pagination
'
;
import
useQueryWithPages
from
'
ui/shared/pagination/useQueryWithPages
'
;
import
RoutedTabs
from
'
ui/shared/Tabs/RoutedTabs
'
;
import
useIsAuth
from
'
ui/snippets/auth/useIsAuth
'
;
import
TxsStats
from
'
ui/txs/TxsStats
'
;
import
TxsWatchlist
from
'
ui/txs/TxsWatchlist
'
;
...
...
@@ -162,15 +164,15 @@ const Transactions = () => {
return
(
<
Flex
alignItems=
"center"
gap=
{
6
}
>
{
isAdvancedFilterEnabled
&&
(
<
Link
Internal
href=
"/advanced-filter"
<
Link
href=
{
route
({
pathname
:
'
/advanced-filter
'
})
}
alignItems=
"center"
display=
"flex"
gap=
{
1
}
>
<
IconSvg
name=
"filter"
boxSize=
{
5
}
/>
Advanced filter
</
Link
Internal
>
</
Link
>
)
}
{
pagination
.
isVisible
&&
<
Pagination
my=
{
1
}
{
...
pagination
}
/>
}
</
Flex
>
...
...
@@ -186,7 +188,7 @@ const Transactions = () => {
<
TxsStats
/>
<
RoutedTabs
tabs=
{
tabs
}
tabL
istProps=
{
isMobile
?
undefined
:
TAB_LIST_PROPS
}
l
istProps=
{
isMobile
?
undefined
:
TAB_LIST_PROPS
}
rightSlot=
{
rightSlot
}
stickyEnabled=
{
!
isMobile
}
/>
...
...
ui/shared/AccountActionsMenu/AccountActionsMenu.tsx
View file @
a86ee441
import
{
Box
,
IconButton
,
MenuButton
,
MenuList
,
chakra
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
chakra
}
from
'
@chakra-ui/react
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
...
...
@@ -7,8 +7,9 @@ import type { ItemProps } from './types';
import
config
from
'
configs/app
'
;
import
*
as
mixpanel
from
'
lib/mixpanel/index
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
Menu
from
'
ui/shared/chakra/Menu
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
{
IconButton
}
from
'
toolkit/chakra/icon-button
'
;
import
{
MenuContent
,
MenuRoot
,
MenuTrigger
}
from
'
toolkit/chakra/menu
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
useProfileQuery
from
'
ui/snippets/auth/useProfileQuery
'
;
...
...
@@ -17,6 +18,7 @@ import PrivateTagMenuItem from './items/PrivateTagMenuItem';
import
PublicTagMenuItem
from
'
./items/PublicTagMenuItem
'
;
import
TokenInfoMenuItem
from
'
./items/TokenInfoMenuItem
'
;
// TODO @tom2drum fix account modals
interface
Props
{
isLoading
?:
boolean
;
className
?:
string
;
...
...
@@ -44,14 +46,14 @@ const AccountActionsMenu = ({ isLoading, className, showUpdateMetadataItem }: Pr
render
:
(
props
:
ItemProps
)
=>
<
MetadataUpdateMenuItem
{
...
props
}
/>,
enabled
:
isTokenInstancePage
&&
showUpdateMetadataItem
,
},
{
render
:
(
props
:
ItemProps
)
=>
<
TokenInfoMenuItem
{
...
props
}
/>,
enabled
:
config
.
features
.
account
.
isEnabled
&&
isTokenPage
&&
config
.
features
.
addressVerification
.
isEnabled
&&
!
userWithoutEmail
,
},
{
render
:
(
props
:
ItemProps
)
=>
<
PrivateTagMenuItem
{
...
props
}
entityType=
{
isTxPage
?
'
tx
'
:
'
address
'
}
/>,
enabled
:
config
.
features
.
account
.
isEnabled
,
},
//
{
//
render: (props: ItemProps) => <TokenInfoMenuItem { ...props }/>,
//
enabled: config.features.account.isEnabled && isTokenPage && config.features.addressVerification.isEnabled && !userWithoutEmail,
//
},
//
{
//
render: (props: ItemProps) => <PrivateTagMenuItem { ...props } entityType={ isTxPage ? 'tx' : 'address' }/>,
//
enabled: config.features.account.isEnabled,
//
},
{
render
:
(
props
:
ItemProps
)
=>
<
PublicTagMenuItem
{
...
props
}
/>,
enabled
:
config
.
features
.
account
.
isEnabled
&&
!
isTxPage
&&
config
.
features
.
publicTagsSubmission
.
isEnabled
,
...
...
@@ -63,7 +65,7 @@ const AccountActionsMenu = ({ isLoading, className, showUpdateMetadataItem }: Pr
}
if
(
isLoading
)
{
return
<
Skeleton
w=
"36px"
h=
"32px"
borderRadius=
"base"
className=
{
className
}
/>;
return
<
Skeleton
loading
w=
"36px"
h=
"32px"
borderRadius=
"base"
className=
{
className
}
/>;
}
if
(
items
.
length
===
1
)
{
...
...
@@ -75,26 +77,20 @@ const AccountActionsMenu = ({ isLoading, className, showUpdateMetadataItem }: Pr
}
return
(
<
Menu
>
<
MenuButton
as=
{
IconButton
}
className=
{
className
}
size=
"sm"
variant=
"outline"
colorScheme=
"gray"
px=
"7px"
onClick=
{
handleButtonClick
}
icon=
{
<
IconSvg
name=
"dots"
boxSize=
"18px"
/>
}
aria
-
label=
"Show address menu"
/>
<
MenuList
minWidth=
"180px"
zIndex=
"popover"
>
<
MenuRoot
>
<
MenuTrigger
asChild
>
<
IconButton
variant=
"dropdown"
size=
"sm"
className=
{
className
}
onClick=
{
handleButtonClick
}
aria
-
label=
"Show address menu"
>
<
IconSvg
name=
"dots"
boxSize=
"18px"
/>
</
IconButton
>
</
MenuTrigger
>
<
MenuContent
>
{
items
.
map
(({
render
},
index
)
=>
(
<
React
.
Fragment
key=
{
index
}
>
{
render
({
type
:
'
menu_item
'
,
hash
})
}
</
React
.
Fragment
>
))
}
</
Menu
Lis
t
>
</
Menu
>
</
Menu
Conten
t
>
</
Menu
Root
>
);
};
...
...
ui/shared/AccountActionsMenu/items/MetadataUpdateMenuItem.tsx
View file @
a86ee441
...
...
@@ -8,7 +8,7 @@ import { useMetadataUpdateContext } from 'ui/tokenInstance/contexts/metadataUpda
import
ButtonItem
from
'
../parts/ButtonItem
'
;
import
MenuItem
from
'
../parts/MenuItem
'
;
const
MetadataUpdateMenuItem
=
({
type
,
className
}:
ItemProps
)
=>
{
const
MetadataUpdateMenuItem
=
({
type
}:
ItemProps
)
=>
{
const
{
status
,
setStatus
}
=
useMetadataUpdateContext
()
||
{};
...
...
@@ -24,15 +24,14 @@ const MetadataUpdateMenuItem = ({ type, className }: ItemProps) => {
label=
"Refresh metadata"
icon=
"refresh"
onClick=
{
handleClick
}
className=
{
className
}
isDisabled=
{
status
===
'
WAITING_FOR_RESPONSE
'
}
/>
);
}
case
'
menu_item
'
:
{
return
(
<
MenuItem
className=
{
className
}
onClick=
{
handleClick
}
isDisabled=
{
status
===
'
WAITING_FOR_RESPONSE
'
}
>
<
IconSvg
name=
"refresh"
boxSize=
{
5
}
mr=
{
2
}
/>
<
MenuItem
onClick=
{
handleClick
}
isDisabled=
{
status
===
'
WAITING_FOR_RESPONSE
'
}
value=
"refresh-metadata"
>
<
IconSvg
name=
"refresh"
boxSize=
{
5
}
/>
<
span
>
Refresh metadata
</
span
>
</
MenuItem
>
);
...
...
ui/shared/AccountActionsMenu/items/PrivateTagMenuItem.tsx
View file @
a86ee441
import
{
useDisclosure
}
from
'
@chakra-ui/react
'
;
import
{
useQueryClient
}
from
'
@tanstack/react-query
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
...
...
@@ -9,6 +8,7 @@ import type { Transaction } from 'types/api/transaction';
import
{
getResourceKey
}
from
'
lib/api/useApiQuery
'
;
import
getPageType
from
'
lib/mixpanel/getPageType
'
;
import
{
useDisclosure
}
from
'
toolkit/hooks/useDisclosure
'
;
import
AddressModal
from
'
ui/privateTags/AddressModal/AddressModal
'
;
import
TransactionModal
from
'
ui/privateTags/TransactionModal/TransactionModal
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
...
...
@@ -21,7 +21,7 @@ interface Props extends ItemProps {
entityType
?:
'
address
'
|
'
tx
'
;
}
const
PrivateTagMenuItem
=
({
className
,
hash
,
entityType
=
'
address
'
,
type
}:
Props
)
=>
{
const
PrivateTagMenuItem
=
({
hash
,
entityType
=
'
address
'
,
type
}:
Props
)
=>
{
const
modal
=
useDisclosure
();
const
queryClient
=
useQueryClient
();
const
router
=
useRouter
();
...
...
@@ -46,7 +46,7 @@ const PrivateTagMenuItem = ({ className, hash, entityType = 'address', type }: P
const
pageType
=
getPageType
(
router
.
pathname
);
const
modalProps
=
{
isOpen
:
modal
.
isO
pen
,
isOpen
:
modal
.
o
pen
,
onClose
:
modal
.
onClose
,
onSuccess
:
handleAddPrivateTag
,
pageType
,
...
...
@@ -58,7 +58,7 @@ const PrivateTagMenuItem = ({ className, hash, entityType = 'address', type }: P
return
(
<
AuthGuard
onAuthSuccess=
{
modal
.
onOpen
}
>
{
({
onClick
})
=>
(
<
ButtonItem
label=
"Add private tag"
icon=
"privattags"
onClick=
{
onClick
}
className=
{
className
}
/>
<
ButtonItem
label=
"Add private tag"
icon=
"privattags"
onClick=
{
onClick
}
/>
)
}
</
AuthGuard
>
);
...
...
@@ -67,7 +67,7 @@ const PrivateTagMenuItem = ({ className, hash, entityType = 'address', type }: P
return
(
<
AuthGuard
onAuthSuccess=
{
modal
.
onOpen
}
>
{
({
onClick
})
=>
(
<
MenuItem
className=
{
className
}
onClick=
{
onClick
}
>
<
MenuItem
onClick=
{
onClick
}
value=
"add-private-tag"
>
<
IconSvg
name=
"privattags"
boxSize=
{
6
}
mr=
{
2
}
/>
<
span
>
Add private tag
</
span
>
</
MenuItem
>
...
...
ui/shared/AccountActionsMenu/items/PublicTagMenuItem.tsx
View file @
a86ee441
...
...
@@ -8,7 +8,7 @@ import IconSvg from 'ui/shared/IconSvg';
import
ButtonItem
from
'
../parts/ButtonItem
'
;
import
MenuItem
from
'
../parts/MenuItem
'
;
const
PublicTagMenuItem
=
({
className
,
hash
,
type
}:
ItemProps
)
=>
{
const
PublicTagMenuItem
=
({
hash
,
type
}:
ItemProps
)
=>
{
const
router
=
useRouter
();
const
handleClick
=
React
.
useCallback
(()
=>
{
...
...
@@ -17,11 +17,11 @@ const PublicTagMenuItem = ({ className, hash, type }: ItemProps) => {
switch
(
type
)
{
case
'
button
'
:
{
return
<
ButtonItem
label=
"Add public tag"
icon=
"publictags"
onClick=
{
handleClick
}
className=
{
className
}
/>;
return
<
ButtonItem
label=
"Add public tag"
icon=
"publictags"
onClick=
{
handleClick
}
/>;
}
case
'
menu_item
'
:
{
return
(
<
MenuItem
className=
{
className
}
onClick=
{
handleClick
}
>
<
MenuItem
onClick=
{
handleClick
}
value=
"add-public-tag"
>
<
IconSvg
name=
"publictags"
boxSize=
{
6
}
mr=
{
2
}
/>
<
span
>
Add public tag
</
span
>
</
MenuItem
>
...
...
ui/shared/AccountActionsMenu/items/TokenInfoMenuItem.tsx
View file @
a86ee441
import
{
chakra
,
useDisclosure
}
from
'
@chakra-ui/react
'
;
import
{
chakra
}
from
'
@chakra-ui/react
'
;
import
{
useRouter
}
from
'
next/router
'
;
import
React
from
'
react
'
;
...
...
@@ -7,6 +7,7 @@ import type { ItemProps } from '../types';
import
config
from
'
configs/app
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
{
PAGE_TYPE_DICT
}
from
'
lib/mixpanel/getPageType
'
;
import
{
useDisclosure
}
from
'
toolkit/hooks/useDisclosure
'
;
import
AddressVerificationModal
from
'
ui/addressVerification/AddressVerificationModal
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
AuthGuard
from
'
ui/snippets/auth/AuthGuard
'
;
...
...
@@ -15,7 +16,7 @@ import useIsAuth from 'ui/snippets/auth/useIsAuth';
import
ButtonItem
from
'
../parts/ButtonItem
'
;
import
MenuItem
from
'
../parts/MenuItem
'
;
const
TokenInfoMenuItem
=
({
className
,
hash
,
type
}:
ItemProps
)
=>
{
const
TokenInfoMenuItem
=
({
hash
,
type
}:
ItemProps
)
=>
{
const
router
=
useRouter
();
const
modal
=
useDisclosure
();
const
isAuth
=
useIsAuth
();
...
...
@@ -72,7 +73,7 @@ const TokenInfoMenuItem = ({ className, hash, type }: ItemProps) => {
return
(
<
AuthGuard
onAuthSuccess=
{
onAuthSuccess
}
>
{
({
onClick
})
=>
(
<
ButtonItem
label=
{
label
}
icon=
{
icon
}
onClick=
{
onClick
}
className=
{
className
}
/>
<
ButtonItem
label=
{
label
}
icon=
{
icon
}
onClick=
{
onClick
}
/>
)
}
</
AuthGuard
>
);
...
...
@@ -81,7 +82,7 @@ const TokenInfoMenuItem = ({ className, hash, type }: ItemProps) => {
return
(
<
AuthGuard
onAuthSuccess=
{
onAuthSuccess
}
>
{
({
onClick
})
=>
(
<
MenuItem
className=
{
className
}
onClick=
{
onClick
}
>
<
MenuItem
onClick=
{
onClick
}
value=
"add-token-info"
>
{
icon
}
<
chakra
.
span
ml=
{
2
}
>
{
label
}
</
chakra
.
span
>
</
MenuItem
>
...
...
@@ -98,7 +99,7 @@ const TokenInfoMenuItem = ({ className, hash, type }: ItemProps) => {
<
AddressVerificationModal
defaultAddress=
{
hash
}
pageType=
{
PAGE_TYPE_DICT
[
'
/token/[hash]
'
]
}
isOpen=
{
modal
.
isO
pen
}
isOpen=
{
modal
.
o
pen
}
onClose=
{
modal
.
onClose
}
onSubmit=
{
handleVerifiedAddressSubmit
}
onAddTokenInfoClick=
{
handleAddApplicationClick
}
...
...
ui/shared/AccountActionsMenu/parts/ButtonItem.tsx
View file @
a86ee441
import
{
IconButton
,
Tooltip
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
{
IconButton
}
from
'
toolkit/chakra/icon-button
'
;
import
{
Tooltip
}
from
'
toolkit/chakra/tooltip
'
;
import
type
{
IconName
}
from
'
ui/shared/IconSvg
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
...
...
@@ -14,17 +15,18 @@ interface Props {
const
ButtonItem
=
({
className
,
label
,
onClick
,
icon
,
isDisabled
}:
Props
)
=>
{
return
(
<
Tooltip
label=
{
label
}
isD
isabled=
{
isDisabled
}
>
<
Tooltip
content=
{
label
}
d
isabled=
{
isDisabled
}
>
<
IconButton
aria
-
label=
{
label
}
className=
{
className
}
icon=
{
typeof
icon
===
'
string
'
?
<
IconSvg
name=
{
icon
}
boxSize=
{
6
}
/>
:
icon
}
onClick=
{
onClick
}
isD
isabled=
{
isDisabled
}
d
isabled=
{
isDisabled
}
size=
"sm"
variant=
"outline"
px=
"4px"
/>
>
{
typeof
icon
===
'
string
'
?
<
IconSvg
name=
{
icon
}
boxSize=
{
6
}
/>
:
icon
}
</
IconButton
>
</
Tooltip
>
);
};
...
...
ui/shared/AccountActionsMenu/parts/MenuItem.tsx
View file @
a86ee441
import
{
MenuItem
as
MenuItemChakra
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
{
MenuItem
as
MenuItemChakra
}
from
'
toolkit/chakra/menu
'
;
interface
Props
{
className
?:
string
;
children
:
React
.
ReactNode
;
onClick
:
()
=>
void
;
value
:
string
;
isDisabled
?:
boolean
;
}
const
MenuItem
=
({
className
,
children
,
onClick
,
isDisabled
}:
Props
)
=>
{
const
MenuItem
=
({
className
,
children
,
onClick
,
value
,
isDisabled
}:
Props
)
=>
{
return
(
<
MenuItemChakra
className=
{
className
}
onClick=
{
onClick
}
py=
{
2
}
px=
{
4
}
isDisabled=
{
isDisabled
}
>
<
MenuItemChakra
className=
{
className
}
onClick=
{
onClick
}
disabled=
{
isDisabled
}
value=
{
value
}
>
{
children
}
</
MenuItemChakra
>
);
...
...
ui/shared/AccountActionsMenu/types.ts
View file @
a86ee441
export
type
ItemType
=
'
button
'
|
'
menu_item
'
;
export
interface
ItemProps
{
className
?:
string
;
type
:
ItemType
;
hash
:
string
;
}
ui/shared/ContainerWithScrollY.tsx
View file @
a86ee441
import
{
Flex
,
useColorModeValue
,
chakra
}
from
'
@chakra-ui/react
'
;
import
{
Flex
,
chakra
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
export
type
Props
=
{
...
...
@@ -22,8 +22,6 @@ const ContainerWithScrollY = ({ className, gradientHeight, children, onScrollVis
onScrollVisibilityChange
?.(
hasScroll
);
},
[
gradientHeight
,
onScrollVisibilityChange
]);
const
gradientEndColor
=
useColorModeValue
(
'
white
'
,
'
black
'
);
return
(
<
Flex
flexDirection=
"column"
...
...
@@ -37,7 +35,7 @@ const ContainerWithScrollY = ({ className, gradientHeight, children, onScrollVis
left
:
0
,
right
:
'
20px
'
,
height
:
`${ gradientHeight }px`
,
bgGradient
:
`linear(to-b, transparent, ${ gradientEndColor })`
,
bgGradient
:
{
_light
:
`linear(to-b, transparent, {colors.white}`
,
_dark
:
`linear(to-b, transparent, {colors.black})`
}
,
}
:
undefined
}
pr=
{
hasScroll
?
5
:
0
}
pb=
{
hasScroll
?
`${ gradientHeight }px`
:
0
}
...
...
ui/shared/DetailsInfoItemDivider.tsx
View file @
a86ee441
import
type
{
ResponsiveValue
}
from
'
@chakra-ui/react
'
;
import
type
{
GridItemProps
}
from
'
@chakra-ui/react
'
;
import
{
GridItem
,
chakra
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
interface
Props
{
className
?:
string
;
id
?:
string
;
colSpan
?:
ResponsiveValue
<
number
|
'
auto
'
>
;
colSpan
?:
GridItemProps
[
'
colSpan
'
]
;
}
const
DetailsInfoItemDivider
=
({
className
,
id
,
colSpan
}:
Props
)
=>
{
...
...
ui/shared/RawInputData.tsx
View file @
a86ee441
import
{
createListCollection
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
hexToUtf8
from
'
lib/hexToUtf8
'
;
import
{
SelectItem
,
SelectContent
,
SelectValueText
,
SelectRoot
,
SelectControl
}
from
'
toolkit/chakra/select
'
;
import
RawDataSnippet
from
'
ui/shared/RawDataSnippet
'
;
import
Select
from
'
ui/shared/select/Select
'
;
const
OPTIONS
=
[
{
label
:
'
Hex
'
,
value
:
'
Hex
'
as
const
},
{
label
:
'
UTF-8
'
,
value
:
'
UTF-8
'
as
const
},
];
const
collection
=
createListCollection
({
items
:
OPTIONS
,
});
export
type
DataType
=
(
typeof
OPTIONS
)[
number
][
'
value
'
];
interface
Props
{
...
...
@@ -22,17 +27,30 @@ interface Props {
const
RawInputData
=
({
hex
,
rightSlot
:
rightSlotProp
,
defaultDataType
=
'
Hex
'
,
isLoading
,
minHeight
}:
Props
)
=>
{
const
[
selectedDataType
,
setSelectedDataType
]
=
React
.
useState
<
DataType
>
(
defaultDataType
);
const
handleValueChange
=
React
.
useCallback
(({
value
}:
{
value
:
Array
<
string
>
})
=>
{
setSelectedDataType
(
value
[
0
]
as
DataType
);
},
[]);
const
rightSlot
=
(
<>
<
Select
options=
{
OPTIONS
}
<
SelectRoot
name=
"data-type"
defaultValue=
{
defaultDataType
}
onChange=
{
setSelectedDataType
}
isLoading=
{
isLoading
}
w=
"90px"
mr=
"auto"
/>
collection=
{
collection
}
variant=
"outline"
defaultValue=
{
[
defaultDataType
]
}
onValueChange=
{
handleValueChange
}
>
<
SelectControl
w=
"100px"
mr=
"auto"
loading=
{
isLoading
}
>
<
SelectValueText
placeholder=
"Select framework"
/>
</
SelectControl
>
<
SelectContent
>
{
collection
.
items
.
map
((
item
)
=>
(
<
SelectItem
item=
{
item
}
key=
{
item
.
value
}
>
{
item
.
label
}
</
SelectItem
>
))
}
</
SelectContent
>
</
SelectRoot
>
{
rightSlotProp
}
</>
);
...
...
ui/shared/alerts/TestnetWarning.tsx
View file @
a86ee441
import
{
Alert
,
chakra
}
from
'
@chakra-ui/react
'
;
import
{
chakra
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
config
from
'
configs/app
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
{
Alert
}
from
'
toolkit/chakra/alert
'
;
interface
Props
{
isLoading
?:
boolean
;
...
...
@@ -15,9 +15,7 @@ const TestnetWarning = ({ isLoading, className }: Props) => {
}
return
(
<
Skeleton
className=
{
className
}
isLoaded=
{
!
isLoading
}
>
<
Alert
status=
"warning"
>
This is a testnet transaction only
</
Alert
>
</
Skeleton
>
<
Alert
status=
"warning"
loading=
{
isLoading
}
className=
{
className
}
>
This is a testnet transaction only
</
Alert
>
);
};
...
...
ui/shared/chakra/Menu.tsx
deleted
100644 → 0
View file @
a19110b6
import
type
{
MenuProps
}
from
'
@chakra-ui/react
'
;
// eslint-disable-next-line no-restricted-imports
import
{
Menu
as
MenuBase
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
const
Menu
=
(
props
:
MenuProps
)
=>
{
return
<
MenuBase
gutter=
{
4
}
{
...
props
}
/>;
};
export
default
React
.
memo
(
Menu
);
ui/shared/logs/LogDecodedInputDataHeader.tsx
View file @
a86ee441
import
{
Divide
r
,
Flex
,
VStack
}
from
'
@chakra-ui/react
'
;
import
{
Separato
r
,
Flex
,
VStack
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
Tag
from
'
ui/shared/chakra/Tag
'
;
import
{
Badge
}
from
'
toolkit/chakra/badge
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
interface
Props
{
methodId
:
string
;
...
...
@@ -21,7 +21,7 @@ const Item = ({ label, children, isLoading }: { label: string; children: React.R
flexDir=
{
{
base
:
'
column
'
,
lg
:
'
row
'
}
}
alignItems=
{
{
base
:
'
flex-start
'
,
lg
:
'
center
'
}
}
>
<
Skeleton
fontWeight=
{
600
}
w=
{
{
base
:
'
auto
'
,
lg
:
'
80px
'
}
}
flexShrink=
{
0
}
isLoaded=
{
!
isLoading
}
>
<
Skeleton
fontWeight=
{
600
}
w=
{
{
base
:
'
auto
'
,
lg
:
'
80px
'
}
}
flexShrink=
{
0
}
loading=
{
isLoading
}
>
{
label
}
</
Skeleton
>
{
children
}
...
...
@@ -33,20 +33,19 @@ const LogDecodedInputDataHeader = ({ methodId, methodCall, isLoading, rightSlot
return
(
<
VStack
align=
"flex-start"
divider=
{
<
Divider
/>
}
fontSize=
"sm"
lineHeight=
{
5
}
separator=
{
<
Separator
/>
}
textStyle=
"sm"
flexGrow=
{
1
}
w=
"100%"
>
<
Flex
columnGap=
{
2
}
w=
"100%"
>
<
Item
label=
"Method id"
isLoading=
{
isLoading
}
>
<
Tag
isLoading=
{
isLoading
}
>
{
methodId
}
</
Tag
>
<
Badge
loading=
{
isLoading
}
>
{
methodId
}
</
Badge
>
</
Item
>
{
rightSlot
}
</
Flex
>
<
Item
label=
"Call"
isLoading=
{
isLoading
}
>
<
Skeleton
isLoaded=
{
!
isLoading
}
whiteSpace=
"pre-wrap"
w=
"100%"
>
{
methodCall
}
</
Skeleton
>
<
Skeleton
loading=
{
isLoading
}
whiteSpace=
"pre-wrap"
w=
"100%"
>
{
methodCall
}
</
Skeleton
>
</
Item
>
</
VStack
>
);
...
...
ui/shared/logs/LogDecodedInputDataTable.tsx
View file @
a86ee441
import
{
Flex
,
Grid
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
{
Flex
,
Grid
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
DecodedInput
}
from
'
types/api/decodedInput
'
;
import
type
{
ArrayElement
}
from
'
types/utils
'
;
import
Skeleton
from
'
ui/shared/chakra/S
keleton
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/s
keleton
'
;
import
CopyToClipboard
from
'
ui/shared/CopyToClipboard
'
;
import
AddressEntity
from
'
ui/shared/entities/address/AddressEntity
'
;
import
TruncatedValue
from
'
ui/shared/TruncatedValue
'
;
...
...
@@ -22,7 +22,7 @@ const HeaderItem = ({ children, isLoading }: { children: React.ReactNode; isLoad
display=
"inline-block"
width=
"fit-content"
height=
"fit-content"
isLoaded=
{
!
isLoading
}
loading=
{
isLoading
}
>
{
children
}
</
Skeleton
>
...
...
@@ -63,15 +63,14 @@ const Row = ({ name, type, indexed, value, isLoading }: ArrayElement<DecodedInpu
<
TruncatedValue
value=
{
name
}
isLoading=
{
isLoading
}
/>
<
TruncatedValue
value=
{
type
}
isLoading=
{
isLoading
}
/>
{
indexed
!==
undefined
&&
(
<
Skeleton
isLoaded=
{
!
isLoading
}
display=
"inline-block"
>
{
indexed
?
'
true
'
:
'
false
'
}
</
Skeleton
>
<
Skeleton
loading=
{
isLoading
}
display=
"inline-block"
>
{
indexed
?
'
true
'
:
'
false
'
}
</
Skeleton
>
)
}
<
Skeleton
isLoaded=
{
!
isLoading
}
display=
"inline-block"
>
{
content
}
</
Skeleton
>
<
Skeleton
loading=
{
isLoading
}
display=
"inline-block"
>
{
content
}
</
Skeleton
>
</>
);
};
const
LogDecodedInputDataTable
=
({
data
,
isLoading
}:
Props
)
=>
{
const
bgColor
=
useColorModeValue
(
'
blackAlpha.50
'
,
'
whiteAlpha.50
'
);
const
hasIndexed
=
data
.
some
(({
indexed
})
=>
indexed
!==
undefined
);
const
gridTemplateColumnsBase
=
hasIndexed
?
...
...
@@ -84,9 +83,8 @@ const LogDecodedInputDataTable = ({ data, isLoading }: Props) => {
return
(
<
Grid
gridTemplateColumns=
{
{
base
:
gridTemplateColumnsBase
,
lg
:
gridTemplateColumnsLg
}
}
fontSize=
"sm"
lineHeight=
{
5
}
bgColor=
{
bgColor
}
textStyle=
"sm"
bgColor=
{
{
_light
:
'
blackAlpha.50
'
,
_dark
:
'
whiteAlpha.50
'
}
}
p=
{
4
}
mt=
{
2
}
w=
"100%"
...
...
ui/shared/tx/interpretation/TxInterpretation.tsx
View file @
a86ee441
import
{
Tooltip
,
chakra
}
from
'
@chakra-ui/react
'
;
import
{
chakra
}
from
'
@chakra-ui/react
'
;
import
BigNumber
from
'
bignumber.js
'
;
import
React
from
'
react
'
;
...
...
@@ -13,8 +13,9 @@ import config from 'configs/app';
import
dayjs
from
'
lib/date/dayjs
'
;
import
*
as
mixpanel
from
'
lib/mixpanel/index
'
;
import
{
currencyUnits
}
from
'
lib/units
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
Tag
from
'
ui/shared/chakra/Tag
'
;
import
{
Badge
}
from
'
toolkit/chakra/badge
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
{
Tooltip
}
from
'
toolkit/chakra/tooltip
'
;
import
AddressEntity
from
'
ui/shared/entities/address/AddressEntity
'
;
import
EnsEntity
from
'
ui/shared/entities/ens/EnsEntity
'
;
import
TokenEntity
from
'
ui/shared/entities/token/TokenEntity
'
;
...
...
@@ -103,7 +104,7 @@ const TxInterpretationElementByType = (
</
chakra
.
span
>
);
}
return
<
chakra
.
span
color=
"text
_
secondary"
whiteSpace=
"pre"
>
{
value
+
'
'
}
</
chakra
.
span
>;
return
<
chakra
.
span
color=
"text
.
secondary"
whiteSpace=
"pre"
>
{
value
+
'
'
}
</
chakra
.
span
>;
}
case
'
currency
'
:
{
let
numberString
=
''
;
...
...
@@ -119,19 +120,19 @@ const TxInterpretationElementByType = (
return
<
chakra
.
span
>
{
numberString
+
'
'
}
</
chakra
.
span
>;
}
case
'
timestamp
'
:
{
return
<
chakra
.
span
color=
"text
_
secondary"
whiteSpace=
"pre"
>
{
dayjs
(
Number
(
value
)
*
1000
).
format
(
'
MMM DD YYYY
'
)
}
</
chakra
.
span
>;
return
<
chakra
.
span
color=
"text
.
secondary"
whiteSpace=
"pre"
>
{
dayjs
(
Number
(
value
)
*
1000
).
format
(
'
MMM DD YYYY
'
)
}
</
chakra
.
span
>;
}
case
'
method
'
:
{
return
(
<
Tag
<
Badge
colorScheme=
{
value
===
'
Multicall
'
?
'
teal
'
:
'
gray
'
}
isT
runcated
t
runcated
ml=
{
1
}
mr=
{
2
}
verticalAlign=
"text-top"
>
{
value
}
</
Tag
>
</
Badge
>
);
}
}
...
...
@@ -155,9 +156,9 @@ const TxInterpretation = ({ summary, isLoading, addressDataMap, className }: Pro
const
chunks
=
getStringChunks
(
intermediateResult
);
return
(
<
Skeleton
isLoaded=
{
!
isLoading
}
className=
{
className
}
fontWeight=
{
500
}
whiteSpace=
"pre-wrap"
>
<
Tooltip
label
=
"Transaction summary"
>
<
IconSvg
name=
"lightning"
boxSize=
{
5
}
color=
"text
_
secondary"
mr=
{
1
}
verticalAlign=
"text-top"
/>
<
Skeleton
loading=
{
isLoading
}
className=
{
className
}
fontWeight=
{
500
}
whiteSpace=
"pre-wrap"
>
<
Tooltip
content
=
"Transaction summary"
>
<
IconSvg
name=
"lightning"
boxSize=
{
5
}
color=
"text
.
secondary"
mr=
{
1
}
verticalAlign=
"text-top"
/>
</
Tooltip
>
{
chunks
.
map
((
chunk
,
index
)
=>
{
let
content
=
null
;
...
...
@@ -175,7 +176,7 @@ const TxInterpretation = ({ summary, isLoading, addressDataMap, className }: Pro
}
return
(
<
chakra
.
span
key=
{
chunk
+
index
}
>
<
chakra
.
span
color=
"text
_
secondary"
>
{
chunk
.
trim
()
+
(
chunk
.
trim
()
&&
variablesNames
[
index
]
?
'
'
:
''
)
}
</
chakra
.
span
>
<
chakra
.
span
color=
"text
.
secondary"
>
{
chunk
.
trim
()
+
(
chunk
.
trim
()
&&
variablesNames
[
index
]
?
'
'
:
''
)
}
</
chakra
.
span
>
{
index
<
variablesNames
.
length
&&
content
}
</
chakra
.
span
>
);
...
...
ui/showcases/Alerts.tsx
View file @
a86ee441
...
...
@@ -2,6 +2,7 @@ import { Box } from '@chakra-ui/react';
import
React
from
'
react
'
;
import
{
Alert
}
from
'
toolkit/chakra/alert
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
{
TableBody
,
TableColumnHeader
,
TableHeader
,
TableRoot
,
TableRow
}
from
'
toolkit/chakra/table
'
;
import
*
as
SocketNewItemsNotice
from
'
ui/shared/SocketNewItemsNotice
'
;
...
...
@@ -48,6 +49,14 @@ const AlertsShowcase = () => {
</
Section
>
<
Section
>
<
SectionHeader
>
Examples
</
SectionHeader
>
<
SectionSubHeader
>
As Link
</
SectionSubHeader
>
<
SamplesStack
>
<
Sample
>
<
Link
href=
"/"
asChild
>
<
Alert
status=
"info"
title=
"Info"
>
Alert content
</
Alert
>
</
Link
>
</
Sample
>
</
SamplesStack
>
<
SectionSubHeader
>
Inside table (SocketNewItemsNotice)
</
SectionSubHeader
>
<
SamplesStack
>
<
Sample
label=
"loading"
>
...
...
ui/showcases/Button.tsx
View file @
a86ee441
...
...
@@ -2,10 +2,11 @@ import React from 'react';
import
{
Button
}
from
'
toolkit/chakra/button
'
;
import
{
Checkbox
}
from
'
toolkit/chakra/checkbox
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
{
PopoverContent
,
PopoverRoot
,
PopoverTrigger
,
PopoverBody
}
from
'
toolkit/chakra/popover
'
;
import
{
BACKGROUND_DEFAULT
}
from
'
ui/home/HeroBanner
'
;
import
{
Section
,
Container
,
SectionHeader
,
SamplesStack
,
Sample
}
from
'
./parts
'
;
import
{
Section
,
Container
,
SectionHeader
,
SamplesStack
,
Sample
,
SectionSubHeader
}
from
'
./parts
'
;
const
ButtonShowcase
=
()
=>
{
return
(
...
...
@@ -182,6 +183,18 @@ const ButtonShowcase = () => {
</
Sample
>
</
SamplesStack
>
</
Section
>
<
Section
>
<
SectionHeader
>
Examples
</
SectionHeader
>
<
SectionSubHeader
>
As Link
</
SectionSubHeader
>
<
SamplesStack
>
<
Sample
>
<
Link
href=
"/"
asChild
>
<
Button
>
I am link
</
Button
>
</
Link
>
</
Sample
>
</
SamplesStack
>
</
Section
>
</
Container
>
);
};
...
...
ui/showcases/Menu.tsx
0 → 100644
View file @
a86ee441
import
React
from
'
react
'
;
import
{
IconButton
}
from
'
toolkit/chakra/icon-button
'
;
import
{
MenuContent
,
MenuItem
,
MenuRoot
,
MenuTrigger
}
from
'
toolkit/chakra/menu
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
{
Section
,
Container
,
SectionHeader
,
SamplesStack
,
Sample
,
SectionSubHeader
}
from
'
./parts
'
;
const
MenusShowcase
=
()
=>
{
return
(
<
Container
value=
"menus"
>
<
Section
>
<
SectionHeader
>
Variant
</
SectionHeader
>
<
SamplesStack
>
<
Sample
label=
"variant: subtle"
>
<
MenuRoot
>
<
MenuTrigger
asChild
>
<
IconButton
variant=
"dropdown"
size=
"sm"
>
<
IconSvg
name=
"dots"
boxSize=
"18px"
/>
</
IconButton
>
</
MenuTrigger
>
<
MenuContent
>
<
MenuItem
value=
"refresh-metadata"
>
Refresh metadata
</
MenuItem
>
<
MenuItem
value=
"add-token-info"
>
Add token info
</
MenuItem
>
<
MenuItem
value=
"add-private-tag"
>
Add private tag
</
MenuItem
>
<
MenuItem
value=
"add-public-tag"
>
Add public tag
</
MenuItem
>
</
MenuContent
>
</
MenuRoot
>
<
MenuRoot
>
<
MenuTrigger
asChild
>
<
IconButton
variant=
"dropdown"
size=
"sm"
loading
>
<
IconSvg
name=
"dots"
boxSize=
"18px"
/>
</
IconButton
>
</
MenuTrigger
>
<
MenuContent
>
<
MenuItem
value=
"refresh-metadata"
>
Refresh metadata
</
MenuItem
>
<
MenuItem
value=
"add-token-info"
>
Add token info
</
MenuItem
>
<
MenuItem
value=
"add-private-tag"
>
Add private tag
</
MenuItem
>
<
MenuItem
value=
"add-public-tag"
>
Add public tag
</
MenuItem
>
</
MenuContent
>
</
MenuRoot
>
</
Sample
>
</
SamplesStack
>
</
Section
>
<
Section
>
<
SectionHeader
>
Examples
</
SectionHeader
>
<
SectionSubHeader
>
Example 1
</
SectionSubHeader
>
</
Section
>
</
Container
>
);
};
export
default
React
.
memo
(
MenusShowcase
);
ui/tx/TxAllowedPeekers.tsx
View file @
a86ee441
import
{
Flex
,
Link
,
useBoolean
}
from
'
@chakra-ui/react
'
;
import
{
Flex
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
*
as
DetailsInfoItem
from
'
ui/shared/DetailsInfoItem
'
;
import
AddressEntity
from
'
ui/shared/entities/address/AddressEntity
'
;
...
...
@@ -10,8 +11,13 @@ interface Props {
const
CUT_LENGTH
=
2
;
// TODO @tom2drum another variant of CutLink
const
TxAllowedPeekers
=
({
items
}:
Props
)
=>
{
const
[
isExpanded
,
expand
]
=
useBoolean
(
false
);
const
[
isExpanded
,
setIsExpanded
]
=
React
.
useState
(
false
);
const
handleCutLinkClick
=
React
.
useCallback
(()
=>
{
setIsExpanded
((
flag
)
=>
!
flag
);
},
[]);
return
(
<>
...
...
@@ -32,7 +38,7 @@ const TxAllowedPeekers = ({ items }: Props) => {
fontSize=
"sm"
textDecorationLine=
"underline"
textDecorationStyle=
"dashed"
onClick=
{
expand
.
toggle
}
onClick=
{
handleCutLinkClick
}
>
{
isExpanded
?
'
Hide
'
:
'
Show all
'
}
</
Link
>
...
...
ui/tx/TxDetailsDegraded.tsx
View file @
a86ee441
...
...
@@ -132,15 +132,15 @@ const TxDetailsDegraded = ({ hash, txQuery }: Props) => {
React
.
useEffect
(()
=>
{
if
(
!
query
.
isPlaceholderData
&&
hasData
)
{
txQuery
.
setRefetch
OnError
.
on
(
);
txQuery
.
setRefetch
Enabled
(
true
);
}
},
[
hasData
,
query
.
isPlaceholderData
,
txQuery
]);
React
.
useEffect
(()
=>
{
return
()
=>
{
txQuery
.
setRefetch
OnError
.
off
(
);
txQuery
.
setRefetch
Enabled
(
false
);
};
},
[
txQuery
.
setRefetchOnError
]);
},
[
txQuery
]);
if
(
!
query
.
data
)
{
if
(
originalError
&&
isCustomAppError
(
originalError
))
{
...
...
ui/tx/TxSocketAlert.tsx
View file @
a86ee441
import
{
Alert
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
{
Alert
}
from
'
toolkit/chakra/alert
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
interface
Props
{
status
:
'
error
'
|
'
close
'
;
}
...
...
@@ -10,7 +11,11 @@ const TxSocketAlert = ({ status }: Props) => {
'
Connection is lost. Please click here to update transaction info.
'
:
'
An error has occurred while fetching transaction info. Please click here to update.
'
;
return
<
Alert
status=
"warning"
as=
"a"
href=
{
window
.
document
.
location
.
href
}
>
{
text
}
</
Alert
>;
return
(
<
Link
href=
{
window
.
document
.
location
.
href
}
asChild
>
<
Alert
status=
"warning"
>
{
text
}
</
Alert
>
</
Link
>
);
};
export
default
React
.
memo
(
TxSocketAlert
);
ui/tx/TxSubHeading.tsx
View file @
a86ee441
import
{
Box
,
Flex
,
Link
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
Flex
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
AddressParam
}
from
'
types/api/addressParams
'
;
...
...
@@ -7,7 +7,9 @@ import config from 'configs/app';
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
{
NOVES_TRANSLATE
}
from
'
stubs/noves/NovesTranslate
'
;
import
{
TX_INTERPRETATION
}
from
'
stubs/txInterpretation
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
AccountActionsMenu
from
'
ui/shared/AccountActionsMenu/AccountActionsMenu
'
;
// TODO @tom2drum fix app action button
import
AppActionButton
from
'
ui/shared/AppActionButton/AppActionButton
'
;
import
useAppActionData
from
'
ui/shared/AppActionButton/useAppActionData
'
;
import
{
TX_ACTIONS_BLOCK_ID
}
from
'
ui/shared/DetailsActionsWrapper
'
;
...
...
@@ -136,9 +138,9 @@ const TxSubHeading = ({ hash, hasTag, txQuery }: Props) => {
mt=
{
{
base
:
3
,
lg
:
0
}
}
>
{
!
hasTag
&&
<
AccountActionsMenu
isLoading=
{
isLoading
}
/>
}
{
appActionData
&&
(
{
/* {
appActionData && (
<AppActionButton data={ appActionData } txHash={ hash } source="Txn"/>
)
}
) }
*/
}
<
NetworkExplorers
type=
"tx"
pathParam=
{
hash
}
ml=
{
{
base
:
0
,
lg
:
'
auto
'
}
}
/>
</
Flex
>
</
Box
>
...
...
ui/tx/details/TxDetailsFeePerGas.tsx
View file @
a86ee441
...
...
@@ -3,7 +3,7 @@ import React from 'react';
import
config
from
'
configs/app
'
;
import
{
currencyUnits
}
from
'
lib/units
'
;
import
Skeleton
from
'
ui/shared/chakra/S
keleton
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/s
keleton
'
;
import
*
as
DetailsInfoItem
from
'
ui/shared/DetailsInfoItem
'
;
interface
Props
{
...
...
@@ -26,7 +26,7 @@ const TxDetailsFeePerGas = ({ txFee, gasUsed, isLoading }: Props) => {
Fee per gas
</
DetailsInfoItem
.
Label
>
<
DetailsInfoItem
.
Value
>
<
Skeleton
isLoaded=
{
!
isLoading
}
mr=
{
1
}
>
<
Skeleton
loading=
{
isLoading
}
mr=
{
1
}
>
{
BigNumber
(
txFee
).
dividedBy
(
10
**
config
.
chain
.
currency
.
decimals
).
dividedBy
(
gasUsed
).
toFixed
()
}
{
config
.
UI
.
views
.
tx
.
hiddenFields
?.
fee_currency
?
''
:
` ${ currencyUnits.ether }`
}
</
Skeleton
>
...
...
ui/tx/details/TxDetailsGasPrice.tsx
View file @
a86ee441
...
...
@@ -6,7 +6,7 @@ import type { TokenInfo } from 'types/api/token';
import
config
from
'
configs/app
'
;
import
{
WEI
,
WEI_IN_GWEI
}
from
'
lib/consts
'
;
import
{
currencyUnits
}
from
'
lib/units
'
;
import
Skeleton
from
'
ui/shared/chakra/S
keleton
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/s
keleton
'
;
import
*
as
DetailsInfoItem
from
'
ui/shared/DetailsInfoItem
'
;
import
TokenEntity
from
'
ui/shared/entities/token/TokenEntity
'
;
...
...
@@ -24,7 +24,7 @@ const TxDetailsGasPrice = ({ gasPrice, gasToken, isLoading }: Props) => {
const
content
=
(()
=>
{
if
(
gasToken
)
{
return
(
<
Skeleton
isLoaded=
{
!
isLoading
}
display=
"flex"
>
<
Skeleton
loading=
{
isLoading
}
display=
"flex"
>
<
span
>
{
BigNumber
(
gasPrice
).
dividedBy
(
WEI
).
toFixed
()
}
</
span
>
<
TokenEntity
token=
{
gasToken
}
noCopy
onlySymbol
w=
"auto"
ml=
{
1
}
/>
</
Skeleton
>
...
...
@@ -33,10 +33,10 @@ const TxDetailsGasPrice = ({ gasPrice, gasToken, isLoading }: Props) => {
return
(
<>
<
Skeleton
isLoaded=
{
!
isLoading
}
mr=
{
1
}
>
<
Skeleton
loading=
{
isLoading
}
mr=
{
1
}
>
{
BigNumber
(
gasPrice
).
dividedBy
(
WEI
).
toFixed
()
}
{
currencyUnits
.
ether
}
</
Skeleton
>
<
Skeleton
isLoaded=
{
!
isLoading
}
color=
"text_secondary"
>
<
Skeleton
loading=
{
isLoading
}
color=
"text_secondary"
>
<
span
>
(
{
BigNumber
(
gasPrice
).
dividedBy
(
WEI_IN_GWEI
).
toFixed
()
}
{
currencyUnits
.
gwei
}
)
</
span
>
</
Skeleton
>
</>
...
...
ui/tx/details/TxDetailsOther.tsx
View file @
a86ee441
...
...
@@ -23,8 +23,8 @@ const TxDetailsOther = ({ nonce, type, position, queueIndex }: Props) => {
<
Box
key=
"type"
>
<
Text
as=
"span"
fontWeight=
"500"
>
Txn type:
</
Text
>
<
Text
fontWeight=
"600"
as=
"span"
>
{
type
}
</
Text
>
{
type
===
2
&&
<
Text
fontWeight=
"400"
as=
"span"
ml=
{
1
}
variant=
"
secondary"
>
(EIP-1559)
</
Text
>
}
{
type
===
3
&&
<
Text
fontWeight=
"400"
as=
"span"
ml=
{
1
}
variant=
"
secondary"
>
(EIP-4844)
</
Text
>
}
{
type
===
2
&&
<
Text
fontWeight=
"400"
as=
"span"
ml=
{
1
}
color=
"text.
secondary"
>
(EIP-1559)
</
Text
>
}
{
type
===
3
&&
<
Text
fontWeight=
"400"
as=
"span"
ml=
{
1
}
color=
"text.
secondary"
>
(EIP-4844)
</
Text
>
}
</
Box
>
),
queueIndex
!==
undefined
?
(
...
...
@@ -47,10 +47,10 @@ const TxDetailsOther = ({ nonce, type, position, queueIndex }: Props) => {
]
.
filter
(
Boolean
)
.
map
((
item
,
index
)
=>
(
<>
<
React
.
Fragment
key=
{
index
}
>
{
index
!==
0
&&
<
TextSeparator
/>
}
{
item
}
</>
</
React
.
Fragment
>
))
}
</
DetailsInfoItem
.
Value
>
...
...
ui/tx/details/TxDetailsTokenTransfers.tsx
View file @
a86ee441
import
{
GridItem
,
Show
,
Fle
x
}
from
'
@chakra-ui/react
'
;
import
{
GridItem
,
Flex
,
Bo
x
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
TokenTransfer
}
from
'
types/api/tokenTransfer
'
;
import
{
route
}
from
'
nextjs-routes
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
*
as
DetailsInfoItem
from
'
ui/shared/DetailsInfoItem
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
LinkInternal
from
'
ui/shared/links/LinkInternal
'
;
import
TokenTransferSnippet
from
'
ui/shared/TokenTransferSnippet/TokenTransferSnippet
'
;
interface
Props
{
data
:
Array
<
TokenTransfer
>
;
txHash
:
string
;
...
...
@@ -61,12 +60,12 @@ const TxDetailsTokenTransfers = ({ data, txHash, isOverflow }: Props) => {
})
}
{
isOverflow
&&
(
<>
<
Show
above=
"lg"
ssr=
{
false
}
><
GridItem
></
GridItem
></
Show
>
<
Box
hideBelow=
"lg"
><
GridItem
></
GridItem
></
Box
>
<
GridItem
fontSize=
"sm"
alignItems=
"center"
display=
"inline-flex"
pl=
{
{
base
:
'
28px
'
,
lg
:
0
}
}
>
<
IconSvg
name=
"token"
boxSize=
{
6
}
/>
<
Link
Internal
href=
{
viewAllUrl
}
>
<
Link
href=
{
viewAllUrl
}
>
View all
</
Link
Internal
>
</
Link
>
</
GridItem
>
</>
)
}
...
...
ui/tx/details/TxDetailsWithdrawalStatus.tsx
View file @
a86ee441
import
{
Button
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
OptimisticL2WithdrawalStatus
}
from
'
types/api/optimisticL2
'
;
import
config
from
'
configs/app
'
;
import
{
Button
}
from
'
toolkit/chakra/button
'
;
import
TxEntityL1
from
'
ui/shared/entities/tx/TxEntityL1
'
;
import
VerificationSteps
from
'
ui/shared/verificationSteps/VerificationSteps
'
;
...
...
@@ -71,6 +71,7 @@ const TxDetailsWithdrawalStatus = ({ status, l1TxHash }: Props) => {
}
})();
// TODO @tom2drum Button as <a> tags
const
rightSlot
=
hasClaimButton
?
(
<
Button
variant=
"outline"
...
...
ui/tx/details/TxInfo.tsx
View file @
a86ee441
...
...
@@ -3,17 +3,13 @@ import {
Grid
,
GridItem
,
Text
,
Link
,
Spinner
,
Flex
,
Tooltip
,
chakra
,
useColorModeValue
,
HStack
,
}
from
'
@chakra-ui/react
'
;
import
BigNumber
from
'
bignumber.js
'
;
import
React
from
'
react
'
;
import
{
scroller
,
Element
}
from
'
react-scroll
'
;
import
{
SCROLL_L2_BLOCK_STATUSES
}
from
'
types/api/scrollL2
'
;
import
type
{
Transaction
}
from
'
types/api/transaction
'
;
...
...
@@ -29,8 +25,11 @@ import * as arbitrum from 'lib/rollups/arbitrum';
import
{
MESSAGE_DESCRIPTIONS
}
from
'
lib/tx/arbitrumMessageStatusDescription
'
;
import
getConfirmationDuration
from
'
lib/tx/getConfirmationDuration
'
;
import
{
currencyUnits
}
from
'
lib/units
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
Tag
from
'
ui/shared/chakra/Tag
'
;
import
{
Badge
}
from
'
toolkit/chakra/badge
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
{
Tooltip
}
from
'
toolkit/chakra/tooltip
'
;
import
CutLink
from
'
toolkit/components/CutLink/CutLink
'
;
import
CopyToClipboard
from
'
ui/shared/CopyToClipboard
'
;
import
CurrencyValue
from
'
ui/shared/CurrencyValue
'
;
import
*
as
DetailsInfoItem
from
'
ui/shared/DetailsInfoItem
'
;
...
...
@@ -77,21 +76,12 @@ interface Props {
const
TxInfo
=
({
data
,
isLoading
,
socketStatus
}:
Props
)
=>
{
const
[
isExpanded
,
setIsExpanded
]
=
React
.
useState
(
false
);
const
handleCutClick
=
React
.
useCallback
(()
=>
{
const
handleCut
Link
Click
=
React
.
useCallback
(()
=>
{
setIsExpanded
((
flag
)
=>
!
flag
);
scroller
.
scrollTo
(
'
TxInfo__cutLink
'
,
{
duration
:
500
,
smooth
:
true
,
});
},
[]);
const
executionSuccessIconColor
=
useColorModeValue
(
'
blackAlpha.800
'
,
'
whiteAlpha.800
'
);
const
showAssociatedL1Tx
=
React
.
useCallback
(()
=>
{
setIsExpanded
(
true
);
scroller
.
scrollTo
(
'
TxInfo__cutLink
'
,
{
duration
:
500
,
smooth
:
true
,
});
},
[]);
if
(
!
data
)
{
...
...
@@ -102,24 +92,24 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
...
data
.
from
.
private_tags
||
[],
...
data
.
from
.
public_tags
||
[],
...
data
.
from
.
watchlist_names
||
[],
].
map
((
tag
)
=>
<
Tag
key=
{
tag
.
label
}
>
{
tag
.
display_name
}
</
Tag
>);
].
map
((
tag
)
=>
<
Badge
key=
{
tag
.
label
}
>
{
tag
.
display_name
}
</
Badge
>);
const
toAddress
=
data
.
to
?
data
.
to
:
data
.
created_contract
;
const
addressToTags
=
[
...
toAddress
?.
private_tags
||
[],
...
toAddress
?.
public_tags
||
[],
...
toAddress
?.
watchlist_names
||
[],
].
map
((
tag
)
=>
<
Tag
key=
{
tag
.
label
}
>
{
tag
.
display_name
}
</
Tag
>);
].
map
((
tag
)
=>
<
Badge
key=
{
tag
.
label
}
>
{
tag
.
display_name
}
</
Badge
>);
const
executionSuccessBadge
=
toAddress
?.
is_contract
&&
data
.
result
===
'
success
'
?
(
<
Tooltip
label
=
"Contract execution completed"
>
<
Tooltip
content
=
"Contract execution completed"
>
<
chakra
.
span
display=
"inline-flex"
ml=
{
2
}
mr=
{
1
}
>
<
IconSvg
name=
"status/success"
boxSize=
{
4
}
color=
{
executionSuccessIconColor
}
cursor=
"pointer"
/>
<
IconSvg
name=
"status/success"
boxSize=
{
4
}
color=
{
{
_light
:
'
blackAlpha.800
'
,
_dark
:
'
whiteAlpha.800
'
}
}
cursor=
"pointer"
/>
</
chakra
.
span
>
</
Tooltip
>
)
:
null
;
const
executionFailedBadge
=
toAddress
?.
is_contract
&&
Boolean
(
data
.
status
)
&&
data
.
result
!==
'
success
'
?
(
<
Tooltip
label
=
"Error occurred during contract execution"
>
<
Tooltip
content
=
"Error occurred during contract execution"
>
<
chakra
.
span
display=
"inline-flex"
ml=
{
2
}
mr=
{
1
}
>
<
IconSvg
name=
"status/error"
boxSize=
{
4
}
color=
"error"
cursor=
"pointer"
/>
</
chakra
.
span
>
...
...
@@ -151,7 +141,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
</
DetailsInfoItem
.
Label
>
<
DetailsInfoItem
.
Value
flexWrap=
"nowrap"
>
{
data
.
status
===
null
&&
<
Spinner
mr=
{
2
}
size=
"sm"
flexShrink=
{
0
}
/>
}
<
Skeleton
isLoaded=
{
!
isLoading
}
overflow=
"hidden"
>
<
Skeleton
loading=
{
isLoading
}
overflow=
"hidden"
>
<
HashStringShortenDynamic
hash=
{
data
.
hash
}
/>
</
Skeleton
>
<
CopyToClipboard
text=
{
data
.
hash
}
isLoading=
{
isLoading
}
/>
...
...
@@ -178,13 +168,13 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
<
DetailsInfoItem
.
Value
>
<
TxStatus
status=
{
data
.
status
}
errorText=
{
data
.
status
===
'
error
'
?
data
.
result
:
undefined
}
isLoading=
{
isLoading
}
/>
{
data
.
method
&&
(
<
Tag
colorScheme=
{
data
.
method
===
'
Multicall
'
?
'
teal
'
:
'
gray
'
}
isLoading=
{
isLoading
}
isT
runcated
ml=
{
3
}
>
<
Badge
colorScheme=
{
data
.
method
===
'
Multicall
'
?
'
teal
'
:
'
gray
'
}
loading=
{
isLoading
}
t
runcated
ml=
{
3
}
>
{
data
.
method
}
</
Tag
>
</
Badge
>
)
}
{
data
.
arbitrum
?.
contains_message
&&
(
<
Skeleton
isLoaded=
{
!
isLoading
}
onClick=
{
showAssociatedL1Tx
}
>
<
Link
isTruncated
ml=
{
3
}
>
<
Skeleton
loading=
{
isLoading
}
onClick=
{
showAssociatedL1Tx
}
>
<
Link
truncate
ml=
{
3
}
>
{
data
.
arbitrum
?.
contains_message
===
'
incoming
'
?
'
Incoming message
'
:
'
Outgoing message
'
}
</
Link
>
</
Skeleton
>
...
...
@@ -296,7 +286,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
{
Boolean
(
data
.
confirmations
)
&&
(
<>
<
TextSeparator
color=
"gray.500"
/>
<
Skeleton
isLoaded=
{
!
isLoading
}
color=
"text_secondary"
>
<
Skeleton
loading=
{
isLoading
}
color=
"text_secondary"
>
<
span
>
{
data
.
confirmations
}
Block confirmations
</
span
>
</
Skeleton
>
</>
...
...
@@ -340,7 +330,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
isLoading=
{
isLoading
}
number=
{
data
.
zksync
.
batch_number
}
/>
)
:
<
Skeleton
isLoaded=
{
!
isLoading
}
>
Pending
</
Skeleton
>
}
)
:
<
Skeleton
loading=
{
isLoading
}
>
Pending
</
Skeleton
>
}
</
DetailsInfoItem
.
Value
>
</>
)
}
...
...
@@ -356,7 +346,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
<
DetailsInfoItem
.
Value
>
{
data
.
arbitrum
.
batch_number
?
<
BatchEntityL2
isLoading=
{
isLoading
}
number=
{
data
.
arbitrum
.
batch_number
}
/>
:
<
Skeleton
isLoaded=
{
!
isLoading
}
>
Pending
</
Skeleton
>
}
<
Skeleton
loading=
{
isLoading
}
>
Pending
</
Skeleton
>
}
</
DetailsInfoItem
.
Value
>
</>
)
}
...
...
@@ -374,7 +364,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
{
data
.
confirmation_duration
&&
(
<>
<
TextSeparator
color=
"gray.500"
/>
<
Skeleton
isLoaded=
{
!
isLoading
}
color=
"text_secondary"
>
<
Skeleton
loading=
{
isLoading
}
color=
"text_secondary"
>
<
span
>
{
getConfirmationDuration
(
data
.
confirmation_duration
)
}
</
span
>
</
Skeleton
>
</>
...
...
@@ -521,7 +511,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
Sequence tx hash
</
DetailsInfoItem
.
Label
>
<
DetailsInfoItem
.
Value
flexWrap=
"nowrap"
>
<
Skeleton
isLoaded=
{
!
isLoading
}
overflow=
"hidden"
>
<
Skeleton
loading=
{
isLoading
}
overflow=
"hidden"
>
<
HashStringShortenDynamic
hash=
{
data
.
zkevm_sequence_hash
}
/>
</
Skeleton
>
<
CopyToClipboard
text=
{
data
.
zkevm_sequence_hash
}
isLoading=
{
isLoading
}
/>
...
...
@@ -538,7 +528,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
Verify tx hash
</
DetailsInfoItem
.
Label
>
<
DetailsInfoItem
.
Value
flexWrap=
"nowrap"
>
<
Skeleton
isLoaded=
{
!
isLoading
}
overflow=
"hidden"
>
<
Skeleton
loading=
{
isLoading
}
overflow=
"hidden"
>
<
HashStringShortenDynamic
hash=
{
data
.
zkevm_verify_hash
}
/>
</
Skeleton
>
<
CopyToClipboard
text=
{
data
.
zkevm_verify_hash
}
isLoading=
{
isLoading
}
/>
...
...
@@ -629,9 +619,9 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
Gas usage
&
limit by txn
</
DetailsInfoItem
.
Label
>
<
DetailsInfoItem
.
Value
>
<
Skeleton
isLoaded=
{
!
isLoading
}
>
{
BigNumber
(
data
.
gas_used
||
0
).
toFormat
()
}
</
Skeleton
>
<
Skeleton
loading=
{
isLoading
}
>
{
BigNumber
(
data
.
gas_used
||
0
).
toFormat
()
}
</
Skeleton
>
<
TextSeparator
/>
<
Skeleton
isLoaded=
{
!
isLoading
}
>
{
BigNumber
(
data
.
gas_limit
).
toFormat
()
}
</
Skeleton
>
<
Skeleton
loading=
{
isLoading
}
>
{
BigNumber
(
data
.
gas_limit
).
toFormat
()
}
</
Skeleton
>
<
Utilization
ml=
{
4
}
value=
{
BigNumber
(
data
.
gas_used
||
0
).
dividedBy
(
BigNumber
(
data
.
gas_limit
)).
toNumber
()
}
isLoading=
{
isLoading
}
/>
</
DetailsInfoItem
.
Value
>
...
...
@@ -644,7 +634,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
Gas used for L1
</
DetailsInfoItem
.
Label
>
<
DetailsInfoItem
.
Value
>
<
Skeleton
isLoaded=
{
!
isLoading
}
>
{
BigNumber
(
data
.
arbitrum
.
gas_used_for_l1
||
0
).
toFormat
()
}
</
Skeleton
>
<
Skeleton
loading=
{
isLoading
}
>
{
BigNumber
(
data
.
arbitrum
.
gas_used_for_l1
||
0
).
toFormat
()
}
</
Skeleton
>
<
TextSeparator
/>
<
Utilization
ml=
{
4
}
...
...
@@ -660,7 +650,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
Gas used for L2
</
DetailsInfoItem
.
Label
>
<
DetailsInfoItem
.
Value
>
<
Skeleton
isLoaded=
{
!
isLoading
}
>
{
BigNumber
(
data
.
arbitrum
.
gas_used_for_l2
||
0
).
toFormat
()
}
</
Skeleton
>
<
Skeleton
loading=
{
isLoading
}
>
{
BigNumber
(
data
.
arbitrum
.
gas_used_for_l2
||
0
).
toFormat
()
}
</
Skeleton
>
<
TextSeparator
/>
<
Utilization
ml=
{
4
}
...
...
@@ -680,7 +670,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
L1 Gas used
</
DetailsInfoItem
.
Label
>
<
DetailsInfoItem
.
Value
>
<
Skeleton
isLoaded=
{
!
isLoading
}
>
{
BigNumber
(
data
.
scroll
?.
l1_gas_used
||
0
).
toFormat
()
}
</
Skeleton
>
<
Skeleton
loading=
{
isLoading
}
>
{
BigNumber
(
data
.
scroll
?.
l1_gas_used
||
0
).
toFormat
()
}
</
Skeleton
>
</
DetailsInfoItem
.
Value
>
</>
)
}
...
...
@@ -700,21 +690,21 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
</
DetailsInfoItem
.
Label
>
<
DetailsInfoItem
.
Value
>
{
data
.
base_fee_per_gas
&&
(
<
Skeleton
isLoaded=
{
!
isLoading
}
>
<
Skeleton
loading=
{
isLoading
}
>
<
Text
as=
"span"
fontWeight=
"500"
>
Base:
</
Text
>
<
Text
fontWeight=
"600"
as=
"span"
>
{
BigNumber
(
data
.
base_fee_per_gas
).
dividedBy
(
WEI_IN_GWEI
).
toFixed
()
}
</
Text
>
{
(
data
.
max_fee_per_gas
||
data
.
max_priority_fee_per_gas
)
&&
<
TextSeparator
/>
}
</
Skeleton
>
)
}
{
data
.
max_fee_per_gas
&&
(
<
Skeleton
isLoaded=
{
!
isLoading
}
>
<
Skeleton
loading=
{
isLoading
}
>
<
Text
as=
"span"
fontWeight=
"500"
>
Max:
</
Text
>
<
Text
fontWeight=
"600"
as=
"span"
>
{
BigNumber
(
data
.
max_fee_per_gas
).
dividedBy
(
WEI_IN_GWEI
).
toFixed
()
}
</
Text
>
{
data
.
max_priority_fee_per_gas
&&
<
TextSeparator
/>
}
</
Skeleton
>
)
}
{
data
.
max_priority_fee_per_gas
&&
(
<
Skeleton
isLoaded=
{
!
isLoading
}
>
<
Skeleton
loading=
{
isLoading
}
>
<
Text
as=
"span"
fontWeight=
"500"
>
Max priority:
</
Text
>
<
Text
fontWeight=
"600"
as=
"span"
>
{
BigNumber
(
data
.
max_priority_fee_per_gas
).
dividedBy
(
WEI_IN_GWEI
).
toFixed
()
}
</
Text
>
</
Skeleton
>
...
...
@@ -751,7 +741,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
</
DetailsInfoItem
.
Label
>
<
DetailsInfoItem
.
Value
>
<
Text
mr=
{
1
}
>
{
BigNumber
(
data
.
l1_gas_price
).
dividedBy
(
WEI
).
toFixed
()
}
{
currencyUnits
.
ether
}
</
Text
>
<
Text
variant=
"
secondary"
>
(
{
BigNumber
(
data
.
l1_gas_price
).
dividedBy
(
WEI_IN_GWEI
).
toFixed
()
}
{
currencyUnits
.
gwei
}
)
</
Text
>
<
Text
color=
"text.
secondary"
>
(
{
BigNumber
(
data
.
l1_gas_price
).
dividedBy
(
WEI_IN_GWEI
).
toFixed
()
}
{
currencyUnits
.
gwei
}
)
</
Text
>
</
DetailsInfoItem
.
Value
>
</>
)
}
...
...
@@ -793,24 +783,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
)
}
<
TxInfoScrollFees
data=
{
data
}
isLoading=
{
isLoading
}
/>
<
GridItem
colSpan=
{
{
base
:
undefined
,
lg
:
2
}
}
>
<
Element
name=
"TxInfo__cutLink"
>
<
Skeleton
isLoaded=
{
!
isLoading
}
mt=
{
6
}
display=
"inline-block"
>
<
Link
display=
"inline-block"
fontSize=
"sm"
textDecorationLine=
"underline"
textDecorationStyle=
"dashed"
onClick=
{
handleCutClick
}
>
{
isExpanded
?
'
Hide details
'
:
'
View details
'
}
</
Link
>
</
Skeleton
>
</
Element
>
</
GridItem
>
{
isExpanded
&&
(
<>
<
CutLink
loading=
{
isLoading
}
mt=
{
6
}
gridColumn=
{
{
base
:
undefined
,
lg
:
'
1 / 3
'
}
}
isExpanded=
{
isExpanded
}
onClick=
{
handleCutLinkClick
}
>
<
GridItem
colSpan=
{
{
base
:
undefined
,
lg
:
2
}
}
mt=
{
{
base
:
1
,
lg
:
4
}
}
/>
{
data
.
arbitrum
?.
contains_message
&&
data
.
arbitrum
?.
message_related_info
&&
(
...
...
@@ -920,8 +893,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
)
}
{
data
.
zksync
&&
<
ZkSyncL2TxnBatchHashesInfo
data=
{
data
.
zksync
}
isLoading=
{
isLoading
}
/>
}
</>
)
}
</
CutLink
>
</
Grid
>
);
};
...
...
ui/tx/details/TxInfoScrollFees.tsx
View file @
a86ee441
...
...
@@ -6,7 +6,7 @@ import type { Transaction } from 'types/api/transaction';
import
{
WEI_IN_GWEI
}
from
'
lib/consts
'
;
import
{
currencyUnits
}
from
'
lib/units
'
;
import
Skeleton
from
'
ui/shared/chakra/S
keleton
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/s
keleton
'
;
import
CurrencyValue
from
'
ui/shared/CurrencyValue
'
;
import
*
as
DetailsInfoItem
from
'
ui/shared/DetailsInfoItem
'
;
import
TextSeparator
from
'
ui/shared/TextSeparator
'
;
...
...
@@ -68,7 +68,7 @@ export const TxInfoScrollFees = ({ data, isLoading }: Props) => {
</
DetailsInfoItem
.
Label
>
<
DetailsInfoItem
.
Value
>
<
CurrencyValue
value=
{
data
.
scroll
?.
l1_fee_commit_scalar
}
value=
{
String
(
data
.
scroll
?.
l1_fee_commit_scalar
)
}
currency=
{
currencyUnits
.
ether
}
exchangeRate=
{
data
.
exchange_rate
}
flexWrap=
"wrap"
...
...
@@ -86,9 +86,9 @@ export const TxInfoScrollFees = ({ data, isLoading }: Props) => {
L1 Fee Overhead
</
DetailsInfoItem
.
Label
>
<
DetailsInfoItem
.
Value
>
<
Skeleton
isLoaded=
{
!
isLoading
}
>
<
Skeleton
loading=
{
isLoading
}
>
<
CurrencyValue
value=
{
data
.
scroll
?.
l1_fee_overhead
}
value=
{
String
(
data
.
scroll
?.
l1_fee_overhead
)
}
currency=
{
currencyUnits
.
ether
}
exchangeRate=
{
data
.
exchange_rate
}
flexWrap=
"wrap"
...
...
@@ -107,13 +107,13 @@ export const TxInfoScrollFees = ({ data, isLoading }: Props) => {
</
DetailsInfoItem
.
Label
>
<
DetailsInfoItem
.
Value
>
{
data
.
scroll
?.
l1_base_fee
!==
undefined
&&
(
<
Skeleton
isLoaded=
{
!
isLoading
}
>
<
Skeleton
loading=
{
isLoading
}
>
<
Text
as=
"span"
fontWeight=
"500"
>
Base:
</
Text
>
<
Text
fontWeight=
"600"
as=
"span"
>
{
BigNumber
(
data
.
scroll
?.
l1_base_fee
||
0
).
dividedBy
(
WEI_IN_GWEI
).
toFixed
()
}
</
Text
>
</
Skeleton
>
)
}
{
data
.
scroll
?.
l1_fee_scalar
!==
undefined
&&
(
<
Skeleton
isLoaded=
{
!
isLoading
}
>
<
Skeleton
loading=
{
isLoading
}
>
<
TextSeparator
/>
<
Text
as=
"span"
fontWeight=
"500"
>
Scalar:
</
Text
>
<
Text
fontWeight=
"600"
as=
"span"
>
{
BigNumber
(
data
.
scroll
?.
l1_fee_scalar
||
0
).
dividedBy
(
WEI_IN_GWEI
).
toFixed
()
}
</
Text
>
...
...
@@ -132,13 +132,13 @@ export const TxInfoScrollFees = ({ data, isLoading }: Props) => {
</
DetailsInfoItem
.
Label
>
<
DetailsInfoItem
.
Value
>
{
data
.
scroll
?.
l1_blob_base_fee
!==
undefined
&&
(
<
Skeleton
isLoaded=
{
!
isLoading
}
>
<
Skeleton
loading=
{
isLoading
}
>
<
Text
as=
"span"
fontWeight=
"500"
>
Base:
</
Text
>
<
Text
fontWeight=
"600"
as=
"span"
>
{
BigNumber
(
data
.
scroll
?.
l1_blob_base_fee
||
0
).
dividedBy
(
WEI_IN_GWEI
).
toFixed
()
}
</
Text
>
</
Skeleton
>
)
}
{
data
.
scroll
?.
l1_fee_blob_scalar
!==
undefined
&&
(
<
Skeleton
isLoaded=
{
!
isLoading
}
>
<
Skeleton
loading=
{
isLoading
}
>
<
TextSeparator
/>
<
Text
as=
"span"
fontWeight=
"500"
>
Scalar:
</
Text
>
<
Text
fontWeight=
"600"
as=
"span"
>
{
BigNumber
(
data
.
scroll
?.
l1_fee_blob_scalar
||
0
).
dividedBy
(
WEI_IN_GWEI
).
toFixed
()
}
</
Text
>
...
...
ui/tx/details/TxRevertReason.tsx
View file @
a86ee441
import
{
Grid
,
GridItem
,
Text
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
{
Grid
,
GridItem
,
Text
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
TransactionRevertReason
}
from
'
types/api/transaction
'
;
...
...
@@ -10,8 +10,6 @@ import LogDecodedInputData from 'ui/shared/logs/LogDecodedInputData';
type
Props
=
TransactionRevertReason
;
const
TxRevertReason
=
(
props
:
Props
)
=>
{
const
bgColor
=
useColorModeValue
(
'
blackAlpha.50
'
,
'
whiteAlpha.50
'
);
if
(
'
raw
'
in
props
)
{
if
(
!
HEX_REGEXP
.
test
(
props
.
raw
))
{
return
<
Text
>
{
props
.
raw
}
</
Text
>;
...
...
@@ -21,7 +19,7 @@ const TxRevertReason = (props: Props) => {
return
(
<
Grid
bgColor=
{
bgColor
}
bgColor=
{
{
_light
:
'
blackAlpha.50
'
,
_dark
:
'
whiteAlpha.50
'
}
}
p=
{
4
}
fontSize=
"sm"
borderRadius=
"md"
...
...
ui/tx/useTxQuery.tsx
View file @
a86ee441
import
{
useBoolean
}
from
'
@chakra-ui/react
'
;
import
type
{
UseQueryResult
}
from
'
@tanstack/react-query
'
;
import
{
useQueryClient
}
from
'
@tanstack/react-query
'
;
import
{
useRouter
}
from
'
next/router
'
;
...
...
@@ -22,11 +21,7 @@ const rollupFeature = config.features.rollup;
export
type
TxQuery
=
UseQueryResult
<
Transaction
,
ResourceError
<
{
status
:
number
}
>>
&
{
socketStatus
:
'
close
'
|
'
error
'
|
undefined
;
setRefetchOnError
:
{
on
:
()
=>
void
;
off
:
()
=>
void
;
toggle
:
()
=>
void
;
};
setRefetchEnabled
:
(
value
:
boolean
)
=>
void
;
};
interface
Params
{
...
...
@@ -36,7 +31,7 @@ interface Params {
export
default
function
useTxQuery
(
params
?:
Params
):
TxQuery
{
const
[
socketStatus
,
setSocketStatus
]
=
React
.
useState
<
'
close
'
|
'
error
'
>
();
const
[
isRefetchEnabled
,
setRefetchEnabled
]
=
useBoolean
(
false
);
const
[
isRefetchEnabled
,
setRefetchEnabled
]
=
React
.
useState
(
false
);
const
router
=
useRouter
();
const
queryClient
=
useQueryClient
();
...
...
@@ -93,6 +88,6 @@ export default function useTxQuery(params?: Params): TxQuery {
return
React
.
useMemo
(()
=>
({
...
queryResult
,
socketStatus
,
setRefetch
OnError
:
setRefetch
Enabled
,
setRefetchEnabled
,
}),
[
queryResult
,
socketStatus
,
setRefetchEnabled
]);
}
ui/txs/TxsTableItem.tsx
View file @
a86ee441
...
...
@@ -83,8 +83,7 @@ const TxsTableItem = ({ tx, showBlockInfo, currentAddress, enableTimeIncrement,
isLoading=
{
isLoading
}
number=
{
tx
.
block_number
}
noIcon
fontSize=
"sm"
lineHeight=
{
6
}
textStyle=
"sm"
fontWeight=
{
500
}
/>
)
}
...
...
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