Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/big-shirts-learn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'hub': patch
---

add unstaking support
2 changes: 1 addition & 1 deletion apps/hub/.env
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
# – https://vercel.com/docs/cli/env#exporting-development-environment-variables


NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID="123"
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID="7ab664eee6a734b14327cdf4678a3431"
3 changes: 2 additions & 1 deletion apps/hub/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"@tanstack/react-table": "^8.21.3",
"@vercel/analytics": "^1.5.0",
"connectkit": "^1.9.0",
"connectkit-next-siwe": "^0.3.0",
"cva": "1.0.0-beta.1",
"framer-motion": "^12.0.6",
"next": "15.3.0",
Expand All @@ -38,7 +39,7 @@
"rehype-slug": "^6.0.0",
"siwe": "^2.3.2",
"ts-pattern": "^5.6.2",
"viem": "^2.21.1",
"viem": "^2.29.1",
"wagmi": "2.15.2",
"zod": "^3.24.1"
},
Expand Down
24 changes: 9 additions & 15 deletions apps/hub/src/app/_components/connect-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,39 @@

import { Button, ShortenAddress } from '@status-im/status-network/components'
import { ConnectKitButton } from 'connectkit'
import { useAccount } from 'wagmi'

import type { ComponentProps } from 'react'

type Props = {
size?: ComponentProps<typeof Button>['size']
label?: string
shortLabel?: string
className?: string
/** If true, shows the label instead of the shortened address when connected */
alwaysShowLabel?: boolean
}

const ConnectButton = (props: Props) => {
const {
size = '32',
label = 'Connect wallet',
shortLabel = 'Connect',
className,
alwaysShowLabel = false,
} = props

const { address, isConnected } = useAccount()

return (
<ConnectKitButton.Custom>
{({ show }) => {
{({ show, isConnected, address }) => {
return (
<Button
onClick={show}
variant={isConnected ? 'secondary' : 'primary'}
size={size}
className={className}
>
{address && isConnected ? (
{address && isConnected && !alwaysShowLabel ? (
<ShortenAddress address={address} />
) : (
<>
<span className="hidden whitespace-nowrap lg:block">
{label}
</span>
<span className="block whitespace-nowrap lg:hidden">
{shortLabel}
</span>
</>
label
)}
</Button>
)
Expand Down
13 changes: 3 additions & 10 deletions apps/hub/src/app/_components/icons/reject-icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,13 @@ const RejectIcon = (props: SVGProps<SVGSVGElement>) => (
fill="none"
{...props}
>
<g
<path
stroke="#E95460"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={4}
clipPath="url(#a)"
>
<path d="m10.269 10.27 29.46 29.462M25 45.833c11.506 0 20.834-9.328 20.834-20.834S36.506 4.166 25 4.166 4.167 13.493 4.167 24.999c0 11.506 9.327 20.834 20.833 20.834Z" />
</g>
<defs>
<clipPath id="a">
<path fill="#fff" d="M0 0h50v50H0z" />
</clipPath>
</defs>
d="m10.27 10.27 29.46 29.462M25 45.835c11.505 0 20.833-9.328 20.833-20.834S36.505 4.168 24.999 4.168 4.166 13.495 4.166 25.001c0 11.506 9.327 20.834 20.833 20.834Z"
/>
</svg>
)
export default RejectIcon
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,32 @@ export function useActionStatusContent(
showCloseButton: true,
}))

// Unstaking flow
.with(
{
type: 'unstaking',
step: 'initialize',
},
state => ({
title: `Ready to unstake ${formatSNT(state.amount ?? 0, { includeSymbol: true })}`,
description: 'Please sign the message in your wallet.',
state: 'pending',
showCloseButton: true,
})
)
.with({ type: 'unstaking', step: 'processing' }, state => ({
title: `Unstaking ${formatSNT(state.amount ?? 0, { includeSymbol: true })}`,
description: 'Wait a moment...',
state: 'processing',
showCloseButton: false,
}))
.with({ type: 'unstaking', step: 'rejected' }, () => ({
title: 'Request was rejected',
description: 'Request was rejected by user',
state: 'error',
showCloseButton: true,
}))

// Withdraw flow (goes directly to processing, no initialize step)
.with({ type: 'withdraw', step: 'processing' }, state => ({
title: `Withdrawing ${formatSNT(state.amount ?? 0, { includeSymbol: true })}`,
Expand Down
29 changes: 28 additions & 1 deletion apps/hub/src/app/_components/vaults/modals/base-vault-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use client'

import { useEffect } from 'react'

import * as Dialog from '@radix-ui/react-dialog'
import { CloseIcon } from '@status-im/icons/20'

Expand Down Expand Up @@ -32,6 +34,31 @@ export function BaseVaultModal(props: BaseVaultModalProps) {
}
}

// Cleanup pointer-events when modal closes or unmounts
useEffect(() => {
if (open === false) {
// Use setTimeout to ensure this runs after Radix UI's cleanup
const timeoutId = setTimeout(() => {
const body = document.body
if (body) {
body.style.removeProperty('pointer-events')
}
}, 0)

return () => clearTimeout(timeoutId)
}
}, [open])

// Cleanup on unmount
useEffect(() => {
return () => {
const body = document.body
if (body) {
body.style.removeProperty('pointer-events')
}
}
}, [])

return (
<Dialog.Root open={open} onOpenChange={handleOpenChange}>
{trigger && <Dialog.Trigger asChild>{trigger}</Dialog.Trigger>}
Expand All @@ -48,7 +75,7 @@ export function BaseVaultModal(props: BaseVaultModalProps) {
</button>
</Dialog.Close>

<div className="flex flex-col items-center px-4 pb-4 pt-8">
<div className="flex flex-col items-center p-4">
<Dialog.Title asChild>
<div className="flex w-full items-center gap-1.5">
<span className="shrink-0 grow basis-0 text-19 font-semibold text-neutral-100">
Expand Down
Loading
Loading