Skip to content

Commit 6109fac

Browse files
committed
feat: walletd resubscribe
1 parent 0f3b9f0 commit 6109fac

File tree

18 files changed

+558
-98
lines changed

18 files changed

+558
-98
lines changed

.changeset/dull-trees-grow.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'walletd': minor
3+
---
4+
5+
Address generation and addition dialogs now have an option to rescan from a specified height. Closes https://github.com/SiaFoundation/walletd/issues/96
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import {
2+
Panel,
3+
ProgressBar,
4+
Separator,
5+
Text,
6+
} from '@siafoundation/design-system'
7+
import { useRescanStatus } from '@siafoundation/react-walletd'
8+
import { useSyncStatus } from '../hooks/useSyncStatus'
9+
import { formatRelative } from 'date-fns'
10+
import { defaultDatasetRefreshInterval } from '../config/swr'
11+
12+
export function RescanStatus() {
13+
const syncStatus = useSyncStatus()
14+
const rescanStatus = useRescanStatus({
15+
config: {
16+
swr: {
17+
refreshInterval: defaultDatasetRefreshInterval,
18+
},
19+
},
20+
})
21+
22+
if (!rescanStatus.data) {
23+
return null
24+
}
25+
26+
const isScanning = rescanStatus.data.index.height < syncStatus.nodeBlockHeight
27+
28+
if (!isScanning) {
29+
return null
30+
}
31+
32+
return (
33+
<div className="z-20 fixed bottom-5 left-1/2 -translate-x-1/2 flex justify-center">
34+
<Panel className="px-2 py-2 w-[400px] overflow-hidden">
35+
<Text weight="medium" className="pb-2">
36+
Rescanning the blockchain
37+
</Text>
38+
<div className="flex flex-col gap-1">
39+
<ProgressBar
40+
variant="accent"
41+
value={rescanStatus.data.index.height}
42+
max={syncStatus.nodeBlockHeight}
43+
/>
44+
<div className="flex justify-between gap-3">
45+
<Text color="verySubtle" size="12" ellipsis>
46+
{rescanStatus.data.error ? 'Stopped' : 'Scanning...'}
47+
</Text>
48+
<Text color="verySubtle" size="12" noWrap>
49+
{`${rescanStatus.data.index.height.toLocaleString()} / ${syncStatus.nodeBlockHeight.toLocaleString()}`}
50+
</Text>
51+
</div>
52+
</div>
53+
<Separator className="w-full mt-2 mb-1" />
54+
<div className="flex justify-between items-center">
55+
{rescanStatus.data.error && (
56+
<Text color="red" size="12">
57+
Error rescanning the blockchain
58+
</Text>
59+
)}
60+
<div className="flex-1" />
61+
<Text color="subtle" size="12">
62+
Started{' '}
63+
{formatRelative(new Date(rescanStatus.data.startTime), new Date())}
64+
</Text>
65+
</div>
66+
{rescanStatus.data.error && (
67+
<div className="flex flex-col gap-1 overflow-hidden pt-1">
68+
<Text color="contrast" size="12">
69+
{rescanStatus.data.error}
70+
</Text>
71+
</div>
72+
)}
73+
</Panel>
74+
</div>
75+
)
76+
}

apps/walletd/components/WalletContextMenu.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
Unlocked16,
1010
Edit16,
1111
Delete16,
12+
Scan16,
1213
} from '@siafoundation/react-icons'
1314
import { useDialog } from '../contexts/dialog'
1415
import { WalletData } from '../contexts/wallets/types'
@@ -66,6 +67,15 @@ export function WalletContextMenu({
6667
</DropdownMenuLeftSlot>
6768
Delete wallet
6869
</DropdownMenuItem>
70+
<DropdownMenuItem
71+
onClick={(e) => e.stopPropagation()}
72+
onSelect={() => openDialog('walletsRescan')}
73+
>
74+
<DropdownMenuLeftSlot>
75+
<Scan16 />
76+
</DropdownMenuLeftSlot>
77+
Rescan blockchain
78+
</DropdownMenuItem>
6979
</DropdownMenu>
7080
)
7181
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import {
2+
DropdownMenu,
3+
DropdownMenuItem,
4+
DropdownMenuLeftSlot,
5+
DropdownMenuLabel,
6+
} from '@siafoundation/design-system'
7+
import { Scan16 } from '@siafoundation/react-icons'
8+
import { useDialog } from '../contexts/dialog'
9+
10+
type Props = Omit<React.ComponentProps<typeof DropdownMenu>, 'children'>
11+
12+
export function WalletsContextMenu({ ...props }: Props) {
13+
const { openDialog } = useDialog()
14+
return (
15+
<DropdownMenu {...props}>
16+
<DropdownMenuLabel>Actions</DropdownMenuLabel>
17+
<DropdownMenuItem
18+
onClick={(e) => e.stopPropagation()}
19+
onSelect={() => openDialog('walletsRescan')}
20+
>
21+
<DropdownMenuLeftSlot>
22+
<Scan16 />
23+
</DropdownMenuLeftSlot>
24+
Rescan blockchain
25+
</DropdownMenuItem>
26+
</DropdownMenu>
27+
)
28+
}

apps/walletd/components/WalletsList/WalletsActionsMenu.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { Button } from '@siafoundation/design-system'
2-
import { Add16, Locked16 } from '@siafoundation/react-icons'
2+
import { Add16, Locked16, Settings16 } from '@siafoundation/react-icons'
33
import { useWallets } from '../../contexts/wallets'
44
import { useDialog } from '../../contexts/dialog'
55
import { WalletsViewDropdownMenu } from './WalletsViewDropdownMenu'
6+
import { WalletsContextMenu } from '../WalletsContextMenu'
67

78
export function WalletsActionsMenu() {
89
const { lockAllWallets, unlockedCount } = useWallets()
@@ -24,6 +25,21 @@ export function WalletsActionsMenu() {
2425
Add wallet
2526
</Button>
2627
<WalletsViewDropdownMenu />
28+
<WalletsContextMenu
29+
trigger={
30+
<Button
31+
size="small"
32+
tip="Wallet settings"
33+
tipAlign="end"
34+
tipSide="bottom"
35+
>
36+
<Settings16 />
37+
</Button>
38+
}
39+
contentProps={{
40+
align: 'end',
41+
}}
42+
/>
2743
</div>
2844
)
2945
}

apps/walletd/config/providers.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { AddressesProvider } from '../contexts/addresses'
55
import { EventsProvider } from '../contexts/events'
66
import { LedgerProvider } from '../contexts/ledger'
77
import { AppProvider } from '../contexts/app'
8+
import { RescanStatus } from '../components/RescanStatus'
89

910
type Props = {
1011
children: React.ReactNode
@@ -21,6 +22,7 @@ export function Providers({ children }: Props) {
2122
{/* this is here so that dialogs can use all the other providers,
2223
and the other providers can trigger dialogs */}
2324
<Dialogs />
25+
<RescanStatus />
2426
{children}
2527
</EventsProvider>
2628
</AddressesProvider>

apps/walletd/contexts/dialog.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ import {
7070
WalletAddressesGenerateLedgerDialog,
7171
WalletAddressesGenerateLedgerDialogParams,
7272
} from '../dialogs/WalletAddressesGenerateLedgerDialog'
73+
import {
74+
WalletsRescanDialogParams,
75+
WalletsRescanDialog,
76+
} from '../dialogs/WalletsRescanDialog'
7377
// import { CmdKDialog } from '../components/CmdKDialog'
7478

7579
export type DialogParams = {
@@ -82,6 +86,7 @@ export type DialogParams = {
8286
addressRemove?: AddressRemoveDialogParams
8387
connectPeer?: SyncerConnectPeerDialogParams
8488
confirm?: ConfirmDialogParams
89+
walletsRescan?: WalletsRescanDialogParams
8590
walletAddType?: WalletAddTypeDialogParams
8691
walletAddNew?: WalletAddNewDialogParams
8792
walletAddRecover?: WalletAddRecoverDialogParams
@@ -240,6 +245,11 @@ export function Dialogs() {
240245
params={params['walletUnlock']}
241246
onOpenChange={(val) => (val ? openDialog(dialog) : closeDialog())}
242247
/>
248+
<WalletsRescanDialog
249+
open={dialog === 'walletsRescan'}
250+
params={params['walletsRescan']}
251+
onOpenChange={(val) => (val ? openDialog(dialog) : closeDialog())}
252+
/>
243253
<AddressUpdateDialog
244254
open={dialog === 'addressUpdate'}
245255
params={params['addressUpdate']}

apps/walletd/contexts/events/index.tsx

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,8 @@ import {
33
useDatasetEmptyState,
44
useServerFilters,
55
} from '@siafoundation/design-system'
6-
import {
7-
useResubscribe,
8-
useWalletEvents,
9-
useWalletTxPool,
10-
} from '@siafoundation/react-walletd'
11-
import { createContext, useCallback, useContext, useMemo } from 'react'
6+
import { useWalletEvents, useWalletTxPool } from '@siafoundation/react-walletd'
7+
import { createContext, useContext, useMemo } from 'react'
128
import {
139
CellContext,
1410
EventData,
@@ -56,13 +52,6 @@ export function useEventsMain() {
5652
},
5753
})
5854

59-
const _resubscribe = useResubscribe()
60-
const resubscribe = useCallback(async () => {
61-
_resubscribe.post({
62-
payload: 0,
63-
})
64-
}, [_resubscribe])
65-
6655
const dataset = useMemo<EventData[] | null>(() => {
6756
if (!responseEvents.data || !responseTxPool.data) {
6857
return null
@@ -204,7 +193,6 @@ export function useEventsMain() {
204193
removeFilter,
205194
removeLastFilter,
206195
resetFilters,
207-
resubscribe,
208196
offset,
209197
limit,
210198
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Alert, Text } from '@siafoundation/design-system'
2+
import { Warning16 } from '@carbon/icons-react'
3+
4+
type Props = {
5+
label: string
6+
description: React.ReactNode
7+
}
8+
9+
export function CalloutWarning({ label, description }: Props) {
10+
return (
11+
<Alert className="!p-2">
12+
<div className="flex flex-col gap-1">
13+
<div className="flex gap-2 items-center">
14+
<Text>
15+
<Warning16 />
16+
</Text>
17+
<Text weight="medium">{label}</Text>
18+
</div>
19+
<Text size="14" color="subtle">
20+
{description}
21+
</Text>
22+
</div>
23+
</Alert>
24+
)
25+
}

0 commit comments

Comments
 (0)