fix(receive): block new addresses during rescan (#1367)

* fix(receive): block new addresses during rescan

* test(receive): click disabled address button
This commit is contained in:
Parth 2026-07-29 16:50:38 +05:30 committed by GitHub
parent 6490a96714
commit ff0a9f229e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 28 additions and 2 deletions

View file

@ -34,6 +34,7 @@ const mocks = vi.hoisted(() => {
return {
developerMode: false,
rescanning: false,
getAddress: vi.fn(),
defaultJars,
jars: defaultJars,
@ -107,6 +108,12 @@ vi.mock('@/context/JamWalletInfoContext', () => ({
}),
}))
vi.mock('@/context/JamSessionInfoContext', () => ({
useRescanStatus: () => ({
rescanInfo: { rescanning: mocks.rescanning },
}),
}))
vi.mock('@/hooks/useApiClient', () => ({
useApiClient: () => ({}),
}))
@ -148,6 +155,7 @@ vi.mock('./ReceiveForm', () => ({
describe('ReceivePage', () => {
beforeEach(() => {
mocks.developerMode = false
mocks.rescanning = false
mocks.jars = mocks.defaultJars
mocks.getAddress.mockReset()
mocks.getAddress.mockResolvedValue({ data: { address: 'bc1qexample' } })
@ -175,6 +183,17 @@ describe('ReceivePage', () => {
await flushActUpdates()
})
it('prevents loading addresses while rescanning', () => {
mocks.rescanning = true
render(<ReceivePage walletFileName="wallet.jmdat" />)
expect(screen.getByRole('button', { name: 'receive.button_reveal_address' })).toBeDisabled()
expect(screen.getByRole('button', { name: 'receive.button_new_address' })).toBeDisabled()
fireEvent.click(screen.getByRole('button', { name: 'receive.button_new_address' }))
expect(mocks.getAddress).not.toHaveBeenCalled()
})
it('uses a secondary jar badge when no jar is available', () => {
mocks.jars = []

View file

@ -10,6 +10,7 @@ import { Button } from '@/components/ui/button'
import { Card, CardContent } from '@/components/ui/card'
import PageTitle from '@/components/ui/jam/PageTitle'
import { Skeleton } from '@/components/ui/skeleton'
import { useRescanStatus } from '@/context/JamSessionInfoContext'
import { useJars } from '@/context/JamWalletInfoContext'
import { useApiClient } from '@/hooks/useApiClient'
import { withMutationDelay } from '@/lib/queryClient'
@ -34,6 +35,7 @@ interface ReceivePageProps {
export const ReceivePage = ({ walletFileName }: ReceivePageProps) => {
const { t } = useTranslation()
const { jars } = useJars()
const { rescanInfo } = useRescanStatus()
const [selectedSourceJarIndex, setSelectedSourceJarIndex] = useState(jars.length > 0 ? jars[0].jarIndex : undefined)
const [amount, setAmount] = useState<AmountSats>()
@ -108,6 +110,7 @@ export const ReceivePage = ({ walletFileName }: ReceivePageProps) => {
}
const fetchNewAddress = async () => {
if (rescanInfo.rescanning) return
await getAddressMutation.mutateAsync()
}
@ -133,7 +136,7 @@ export const ReceivePage = ({ walletFileName }: ReceivePageProps) => {
variant={jarButtonVariant(selectedSourceJarIndex)}
size="lg"
onClick={() => void fetchNewAddress()}
disabled={getAddressMutation.isPending}
disabled={getAddressMutation.isPending || rescanInfo.rescanning}
>
<HatGlassesIcon />
{t('receive.button_reveal_address')}
@ -190,7 +193,11 @@ export const ReceivePage = ({ walletFileName }: ReceivePageProps) => {
</div>
<div className="mt-4 flex flex-wrap items-center justify-center gap-2">
<Button variant="outline" onClick={() => void fetchNewAddress()} disabled={getAddressMutation.isPending}>
<Button
variant="outline"
onClick={() => void fetchNewAddress()}
disabled={getAddressMutation.isPending || rescanInfo.rescanning}
>
{getAddressMutation.isPending ? (
<>
<RefreshCwIcon className="animate-spin motion-reduce:hidden" />